TRANSDUTORES DOMÓTICOS INTELIGENTES - paginas.fe.up.ptee99075/projecto/relatorio.pdf · TDI -...

276
RELATÓRIO FINAL TRANSDUTORES DOMÓTICOS INTELIGENTES PROJECTO REALIZADO POR: ANTÓNIO MIGUEL LISBOA DA SILVA ([email protected]) JOSÉ LUIS ALVES BAPTISTA ([email protected]) ORIENTADOR: PROF. DR. ARMANDO SOUSA ARAÚJO ([email protected]) PORTO, DEZEMBRO DE 2004

Transcript of TRANSDUTORES DOMÓTICOS INTELIGENTES - paginas.fe.up.ptee99075/projecto/relatorio.pdf · TDI -...

RELATÓRIO FINAL

TRANSDUTORES DOMÓTICOS INTELIGENTES

PROJECTO REALIZADO POR:

ANTÓNIO MIGUEL LISBOA DA SILVA ([email protected])

JOSÉ LUIS ALVES BAPTISTA ([email protected])

ORIENTADOR:

PROF. DR. ARMANDO SOUSA ARAÚJO ([email protected])

PORTO, DEZEMBRO DE 2004

TDI - Transdutores domóticos inteligentes

Índice

Abreviaturas e acrónimos .............................................................................................................8 1 – Introdução ................................................................................................................................9

1.1 - O que é a domótica?.........................................................................................................9 1.2 - O sistema EIB (European Installation Bus) ...............................................................14

1.2.1 - Introdução................................................................................................................14 1.2.2 - Descrição funcional ................................................................................................15

1.3 - O sistema LonWorks .....................................................................................................26

1.3.1 – Introdução...............................................................................................................26 1.3.2 - Descrição funcional ................................................................................................29

1.4 - O sistema X-10 ...............................................................................................................39

1.4.1 - Introdução................................................................................................................39 1.4.2 - Descrição funcional ................................................................................................40

1.5 - Principais diferenças entre X10, EIB e LonWorks....................................................46 1.6 - O protocolo X-10...........................................................................................................49

1.6.1 - Aspectos Teóricos...................................................................................................49 1.6.2 - Aspectos Práticos....................................................................................................55

2 - Objectivos e requisitos ..........................................................................................................57 3 – Módulos desenvolvidos ........................................................................................................58

3.1 Introdução..........................................................................................................................58 3.2 Descrição funcional ..........................................................................................................58 3.3 Hardware comum a todos os módulos ..........................................................................60

3.3.1 Alimentação................................................................................................................60 3.3.2 Acoplamento ..............................................................................................................60 3.3.3 Detecção do zero da rede.........................................................................................62 3.3.4 Recepção.....................................................................................................................63 3.3.5 Transmissão................................................................................................................65 3.3.6 Interface RS232..........................................................................................................66

3.4 Software comum a todos os módulos............................................................................67 3.5 - Módulo 1: Módulo “Interface PC” ..............................................................................74

3.5.1 - Descrição do hardware...........................................................................................74 3.5.2 - Descrição do software............................................................................................75

3.6 - Módulo 2: Módulo “Central de inundação” ...............................................................78

3.6.1 - Descrição do hardware...........................................................................................78

TDI - Transdutores domóticos inteligentes

3.6.2 - Descrição do software............................................................................................81

3.7 - Módulo 3: Módulo “Sensor”.........................................................................................82

3.7.1 Descrição do hardware .............................................................................................82 3.7.2 - Descrição do software............................................................................................84

3.8 - Módulo 4: Módulo “Actuador AC”.............................................................................86

3.8.1 - Descrição do hardware...........................................................................................86 3.8.2 - Descrição do software............................................................................................88

3.9 - Módulo 5: Módulo “Actuador DC” ............................................................................90

3.9.1 - Descrição do hardware...........................................................................................90 3.9.2 - Descrição do software............................................................................................92

4 – Aplicação gráfica “X-10 Interface para PC”......................................................................93 5 – Programador para o microcontrolador PIC16F877A......................................................97 6 – BootLoader para o PIC16F877A........................................................................................99

6.1 Programa para o microcontrolador ................................................................................99 6.2 Aplicação gráfica para o PC.......................................................................................... 100

7 – Conclusões........................................................................................................................... 102 8 - Bibliografia ........................................................................................................................... 103 9 - Anexos .................................................................................................................................. 105

Anexo A - Código fonte dos módulos .............................................................................. 105 Anexo B - Código fonte do Bootloader para o micro-controlador. ............................. 202 Anexo C - Código fonte da aplicação gráfica “Bootloader” .......................................... 208 Anexo D - Código fonte da aplicação gráfica “X-10 Interface para PC ...................... 213 Anexo E – Esquemas e negativos das placas ................................................................... 259

TDI - Transdutores domóticos inteligentes

Relatório Final 4/276

Lista de figuras

Fig. 1 – Arquitectura simples ......................................................... 9 Fig. 2 – Interruptores simples e inteligentes...................................... 10 Fig. 3 – Arquitectura distribuída .................................................... 11 Fig. 4 - Método de comunicação CMSA............................................. 13 Fig. 5. Barramento de transmissão (bus) e rede eléctrica ..................... 14 Fig. 6 – Arquitectura descentralizada.............................................. 15 Fig. 7 – Arquitectura centralizada .................................................. 16 Fig. 8 – Barramento cablado......................................................... 17 Fig. 9 – As várias topologias possíveis do bus ..................................... 17 Fig. 10 – Estrutura da hierarquia do sistema EIB ................................. 18 Fig. 11 – Troca de dados codificados entre dispositivos EIB.................... 20 Fig. 12 – Pirâmide de interfuncionamento entre actuadores e sensores ..... 20 Fig. 13 – Bloco de dados.............................................................. 22 Fig. 14 – Estrutura de um telegrama EIB (comprimento medido em bits) ... 22 Fig. 15 – Transmissão e formato do endereço físico dos dispositivos EIB .... 23 Fig. 16 – Transmissão e formato do endereço de grupo em sistemas EIB .... 24 Fig. 17 – Arquitectura centralizada ................................................ 26 Fig. 18 – Estrutura hierárquica típica .............................................. 27 Fig. 19 – Arquitectura mais distribuída da nova tecnologia LonWorks........ 29 Fig. 20 – Rede de dispositivos ....................................................... 30 Fig. 21 – Esquema de um nó individual para uma configuração distribuída . 31 Fig. 22 – Estrutura em blocos de um Chip Neuron ............................... 31 Fig. 23 – Contituição de um MPDU (“frame”)..................................... 33 Fig. 24 – Campo NPDU ................................................................ 34 Fig. 25 - Casa inteligente ............................................................ 39 Fig. 26 – Instalação de dispositivos X-10........................................... 40 Fig. 27 – Outros símbolos identificadores de módulos........................... 40 Fig. 28 – Selectores para atribuição de endereços X-10 ........................ 42 Fig. 29 – Exemplo de uma rede X-10 ............................................... 44 Fig. 30 – Passagens por zero da rede eléctrica ................................... 49 Fig. 31 – Diagrama temporal simplificado da recepção ......................... 49 Fig. 32 – Exemplo da transmissão de dados utilizando .......................... 50 Fig. 33 – Exemplo de um Start Code ............................................... 50 Fig. 34 – Exemplo de um House Code .............................................. 51 Fig. 35 – Exemplo de um number code ............................................ 51 Fig. 36 – Exemplo da transmissão em duplicado da trama ..................... 52 Fig. 37 – Exemplo de um command code.......................................... 52 Fig. 38 – Envio de uma trama completa ........................................... 53 Fig. 39 – Envio de burts para o sistema trifásico ................................ 53 Fig. 40 – Tabela de comandos ....................................................... 54 Fig. 41 – Formato da trama estendida ............................................. 54 Fig. 42 – Tempo entre bursts ........................................................ 55 Fig. 43 – Tempo máximo aconselhado para o envio do primeiro burst ....... 55 Fig. 44 - Diagrama de blocos geral dos módulos desenvolvidos ............... 59 Fig. 45 - Alimentação dos módulos ................................................. 60 Fig. 46 - Acoplamento com a rede eléctrica...................................... 61

TDI - Transdutores domóticos inteligentes

Relatório Final 5/276

Fig. 47 - Acoplamento utilizando um conjunto de filtro LC .................... 61 Fig. 48 - Acoplamento utilizando um transformador HF ........................ 62 Fig. 49 - Detecção da passagem por zero da rede ............................... 62 Fig. 50 - Sinal à saída do opto-acoplador ......................................... 63 Fig. 51 - Diagrama de blocos do circuito da recepção .......................... 63 Fig. 52 - Esquema eléctrico da recepção.......................................... 64 Fig. 53 - Sinal à saída do bloco de recepção...................................... 65 Fig. 54 - Esquema eléctrico da recepção.......................................... 65 Fig. 55 - Sinal à saída do bloco de transmissão .................................. 66 Fig. 56 - Esquema eléctrico da interface RS232.................................. 66 Fig. 57 - Fotografia do módulo RS232.............................................. 67 Fig. 58 – Fluxograma do programa principal ...................................... 70 Fig. 59 – Fluxograma da interrupção ............................................... 71 Fig. 60 - Diagrama de blocos do módulo “Interface PC”........................ 74 Fig. 61 - Fotografia do módulo “Interface PC”................................... 75 Fig. 62 – Formato da trama.......................................................... 75 Fig. 63 – Formato da trama para comandos standard ........................... 76 Fig. 64 – Formato da trama para comandos estendidos......................... 76 Fig. 65 – Confirmação do envio do comando...................................... 76 Fig. 66 – Fluxograma do programa principal ...................................... 77 Fig. 67 - Diagrama de blocos do módulo “Central de inundação”............. 78 Fig. 68 – Circuito de um dos sensores de inundação............................. 79 Fig. 69 – Circuito para o buzzer..................................................... 79 Fig. 70 – Circuito para o botão de pressão ........................................ 79 Fig. 71 - Fotografias dos eléctrodos................................................ 80 Fig. 72 - Fotografia do módulo “Central de inundação” ........................ 80 Fig. 73 – Fluxograma do programa principal ...................................... 81 Fig. 74 - Diagrama de blocos do módulo “Sensor”............................... 82 Fig. 75 – Circuito da interface para o sensor ..................................... 83 Fig. 76 - Fotografia do PIR (Sensor de Movimento) .............................. 83 Fig. 77 - Fotografia do módulo “Sensor” .......................................... 84 Fig. 78 – Fluxograma do programa principal ...................................... 85 Fig. 79 - Diagrama de blocos do módulo “Actuador AC”........................ 86 Fig. 80 – Circuito da interface para controlar cargas AC ....................... 87 Fig. 81 - Fotografia do módulo “Actuador AC” ................................... 88 Fig. 82 – Fluxograma do programa principal ...................................... 89 Fig. 83 - Diagrama de blocos do módulo “Actuador DC”........................ 90 Fig. 84 – Circuito da interface para controlar cargas DC ....................... 91 Fig. 85 – Fotografias da electro-válvula e da sirene ............................. 91 Fig. 86 - Fotografia do módulo “Actuador DC”................................... 92 Fig. 87 – Aplicação gráfica “X-10 Interface para PC”............................ 93 Fig. 88 – Definições da porta série ................................................. 94 Fig. 89 – Gestão dos arquivos que contêm a listagem dos módulos ........... 94 Fig. 90 – Janela que permite a inserção de módulos ............................ 95 Fig. 91 – Comandos que permitem o controlo e gestão remota dos módulos95 Fig. 92 – Menus de configuração remota dos módulos .......................... 96 Fig. 93 – Registo da actividade X-10 da rede eléctrica.......................... 96 Fig. 94 - Fotografias do Programador de PICs .................................... 97 Fig. 95 - Configuração do IC-Prog para o programador ......................... 98

TDI - Transdutores domóticos inteligentes

Relatório Final 6/276

Fig. 96 - Diagrama da transmissão entre o PC e o microcontrolador ......... 99 Fig. 97 - Fluxograma do programa para o microcontrolador ................. 100 Fig. 98 – Aplicação gráfica para o bootloader .................................. 101

TDI - Transdutores domóticos inteligentes

Relatório Final 7/276

Lista de quadros

Quadro 1 – Troca de dados codificados entre dispositivos EIB ................. 19 Quadro 2 – Algumas funções EIB com o respectivo EIS .......................... 21 Quadro 3 – Evolução tecnológica do sistema Lon ................................ 32 Quadro 4 – Características referentes a diferentes meios de transmissão... 33 Quadro 5 – Vantagens que o sistema Lon oferece................................ 37 Quadro 6 – Comandos X-10........................................................... 43 Quadro 7. Descrição das opções de agendamento ............................... 72 Quadro 8. Estrutura da EEPROM .................................................... 72 Quadro 9. Descrição dos dados estendidos do tipo 6............................ 73

TDI - Transdutores domóticos inteligentes

Relatório Final 8/276

ABREVIATURAS E ACRÓNIMOS

EIB European Installation Bus Bus Barramento de transmissão CMSA Carrier Sense Multiple Access CMSA/CA Carrier Sense Multiple Access with collision Avoidence EHS European Home Systems RDIS Rede Digital com Integração de Serviço AL Acopladores de Linha AA Acopladores de Área EIS EIB Interworking Standards Lon LonWorks CLP Controlador Lógico Programável VLSI Very Large Scale Integration OME Original Equipment Manufacturer OSI Open System Interconnection MAC Media Access Control MPDU Moderately Priced Dwelling Unit NPDU Network Protocol Data Unit PDU Protocol Data Unit SNVT’s Standard Network Variables RF Rádio Frequência HC House Code UC Unit Code FC Function Code PWM Pulse Width Modulator IC Integrated Circuit

TDI - Transdutores domóticos inteligentes

Relatório Final 9/276

1 – INTRODUÇÃO

1.1 - O QUE É A DOMÓTICA?

O termo “domótica” resulta da junção da palavra “Domus” (casa) com “Telemática” (electrónica + informática). São estes dois últimos elementos que, quando utilizados em casa, simplificam e rentabilizam a vida diária das pessoas satisfazendo as suas necessidades de comunicação, conforto e segurança.

A domótica é pois uma tecnologia recente que permite a gestão de recursos habitacionais, como o aquecimento, os electrodomésticos, o sistema de alarme e as fechaduras, entre outros, através de um comando remoto, da Internet, do seu PC ou do seu telemóvel.

Antes do aparecimento da domótica era normal ligar, com cablagem própria, os sensores aos actuadores. O resultado era uma arquitectura simples, Fig. 1, mas pouco flexível: para incluir novos dispositivos (sensores e actuadores) havia necessidade de serem instalados cabos, os actuadores não podiam ser acedidos por outros sensores e, quando se pretendia efectuar diagnóstico, os dispositivos teriam de ser acedidos localmente.

Fig. 1 – Arquitectura simples

Com o nascimento da domótica (nos anos 80) pretendia-se controlar a iluminação, condições climáticas, a segurança e a interligação entre os 3 elementos. Nos nossos dias, a ideia base é a mesma, a diferença é o contexto para o qual o sistema está pensado: já não um contexto militar ou industrial mas doméstico. Apesar de ainda ser pouco conhecida e divulgada, mas pelo conforto e comodidade que pode proporcionar, a domótica promete vir a ter muitos adeptos.

As primeiras instalações domóticas, Fig. 2, consistiam em alguns sensores, e outros tantos actuadores, interligados a uma unidade central de controlo: um autómato, que agregava toda a inteligência necessária para controlar a habitação. Estes sistemas eram quase sempre proprietários, pouco flexíveis e de custos elevados.

TDI - Transdutores domóticos inteligentes

Relatório Final 10/276

Fig. 2 – Interruptores simples e inteligentes

A domótica, pela automatização e integração dos diferentes sistemas domésticos, assume um papel muito importante na gestão racional da energia, no aumento do conforto e da segurança e na oferta de serviços de comunicação contribuindo para o aumento da nossa qualidade de vida.

Assim a domótica permite:

• A Automatização e Controlo - Utilizando os módulos e aparelhos apropriados, gerir os gastos de electricidade, através das funções de regulação de intensidade;

• A Segurança e Vigilância - De pessoas e bens, gestão e controlo de avarias, alarme de intrusão e incêndio, detecção de fugas de agua e gás, câmaras de vigilância;

• A Comunicação - Redes de voz e dados incluindo imagem e som em redes locais, integração e partilha de recursos entre diferentes redes, acesso à Internet e a novos serviços como telefone sobre IP e televisão digital;

• Os Serviços e Lazer - Televisão interactiva, áudio/vídeo multi-room, cinema em casa, videojogos em rede, captura, tratamento e distribuição de imagens fixas/dinâmicas e de som dentro e fora da casa através de Internet;

• Na Saúde - Tele-medicina, assistência médica à distância;

• Em Compras - Comprar e vender sem sair de casa;

• Nas Finanças - Gestão remota de dinheiro e contas bancárias, consultoria financeira;

• Na Aprendizagem - Escola e universidade on-line;

• No Trabalho - Trabalhar total ou parcialmente em casa;

• Na Cidadania - Voto electrónico, informação judicial e administrativa, informação sobre a região, cultura, museus.

TDI - Transdutores domóticos inteligentes

Relatório Final 11/276

Desde há alguns anos, a baixa dos preços, do hardware, contribuiu para que os fabricantes iniciassem a produção em massa de sensores e actuadores com inteligência suficiente para implementar uma rede local de controlo distribuído, Fig. 3. Com uma arquitectura distribuída e apoiando-se em novas tecnologias standards, como o X10, o LonWorks ou o KNX (que inclui os antigos protocolos EIB, Batibus e EHS).

Assim, as novas instalações domóticas são mais fáceis de implementar e de utilizar, tendo ganho em flexibilidade e modularidade, diminuindo ao mesmo tempo os custos.

Fig. 3 – Arquitectura distribuída

A arquitectura técnica de um sistema domótico assenta sobre três conceitos:

O tipo de arquitectura

A arquitectura de um sistema domótico especifica o modo como os diferentes elementos de controlo do sistema se interligam. Existem duas arquitecturas básicas: a arquitectura centralizada e a distribuída.

• Arquitectura centralizada - neste tipo de arquitectura os elementos a controlar e a supervisionar (sensores, luzes, válvulas, etc.) exigem uma estrutura (cablagem) própria para ligação ao sistema de controlo (PC ou similar). O sistema de controlo é o cérebro da habitação. Em caso de avaria todo o sistema deixa de funcionar, e a instalação da sua rede de comunicação tem de ser feita durante a fase de construção.

• Arquitectura distribuída - é aquela em que o elemento de controlo se encontra próximo do elemento a controlar. Há sistemas que são de arquitectura distribuída quanto a capacidade de processamento, mas não o são na estrutura física dos diferentes elementos de controlo e vice-versa, que são executados em um ou vários processadores fisicamente centralizados. Nos sistemas de arquitectura distribuída que utilizam um meio de transmissão como o cabo ou a fibra é necessário definir a topologia da rede de comunicações. A topologia da rede

TDI - Transdutores domóticos inteligentes

Relatório Final 12/276

define-se como a distribuição física dos elementos de controlo com respeito ao meio de comunicação.

A rede de transmissão

O meio de transmissão é o suporte físico onde circula a informação trocada pelos diferentes elementos de controlo dum sistema de arquitectura distribuída. A transmissão poderá ser feita através da rede eléctrica existente (transmissão por correntes portadoras), duma rede autónoma (por cablagem metálica, por par coaxial, por fibra óptica) ou sem fios (infravermelho ou radiofrequência).

• Transmissão por Correntes Portadoras - utiliza a rede eléctrica existente. O sistema consta de uma unidade de controlo encarregada de gerir o protocolo e transmitir as ordens através da rede; de uma interface que recebe as ordens de controlo e as executa; e de um filtro que evita que sinais exteriores interfiram no sistema e vice-versa. O custo baixo da instalação reflecte-se contudo na velocidade de transmissão igualmente baixa;

• Transmissão por cablagem metálica - utiliza uma cablagem metálica própria (par de cobre) como suporte para a transmissão dos sinais de controlo (e por vezes também a alimentação dos módulos e sinais de voz). Este meio de transmissão é sobretudo utilizado nas redes telefónicas, na distribuição de sinais áudio-vídeo, som de alta-fidelidade e dados;

• Transmissão por par coaxial -utiliza um par coaxial e é principalmente usado na transmissão de sinais de vídeo e sinais de áudio a alta velocidade, na distribuição sinais de televisão provenientes de antenas (redes de TV e FM) e TV por cabo (sinais de controlo e dados a média e baixa velocidade);

• Transmissão por fibra óptica - utiliza uma combinação de tecnologias de semicondutores e de ondas ópticas (a fibra óptica). Este meio de transmissão apresenta grande fiabilidade na transferência de dados e imunidade a interferências electromagnéticas. Apresenta velocidades de transmissão elevadas mas com um custo elevado dos cabos e ligações;

• Transmissão sem fios - através de infravermelhos ou radiofrequência. A transmissão por infravermelhos está amplamente difundida hoje nos equipamentos áudio e vídeo. Apresenta enorme comodidade e flexibilidade nas aplicações, e grande imunidade à interferência electromagnética. A transmissão por radiofrequência apresenta também grande flexibilidade no controlo à distância embora seja mais sensível às interferências electromagnéticas.

A velocidade de transmissão e protocolo de comunicação

Por velocidade de transmissão entende-se como a velocidade à qual se troca informação entre os diferentes módulos do sistema. A velocidade variará conforme o meio de transmissão sendo que a transmissão através da rede eléctrica será mais lenta que por exemplo através duma rede dedicada por fibra óptica. Na transmissão de comandos

TDI - Transdutores domóticos inteligentes

Relatório Final 13/276

simples (ligar/desligar as luzes) a velocidade não será um factor crucial enquanto que no sistema de áudio e vídeo distribuído será necessário assegurar que a informação é transferida a uma velocidade elevada.

Após estabelecer o suporte físico e a velocidade de comunicação pretendida, torna-se necessário definir o protocolo a utilizar na comunicação entre os diferentes aparelhos. O protocolo indicará o formato das mensagens, a “linguagem” comum a todos aparelhos para que se entendam mutuamente. Dentro dos protocolos existentes, faz-se a seguinte distinção:

• Protocolos standard - são os protocolos que de alguma maneira são utilizados amplamente por diferentes empresas e estas fabricam produtos que são compatíveis entre si;

• Protocolos proprietários - são aqueles que são desenvolvidos por uma única empresa e apenas essa empresa fabrica produtos capazes de comunicar entre si.

O formato dos dados (pacotes) depende do protocolo usado pelos diferentes sistemas. Contudo a maior parte dos sistemas domóticos utiliza um protocolo que utiliza o método de comunicação denominado ” Carrier Sense Multiple Access” (CMSA), Fig. 4. Este método contribui para que um dispositivo possa enviar e receber informação pelo mesmo meio de comunicação através de uma activa monitorização ao meio de comunicação. Quando um dispositivo deseja transmitir dados, só o pode fazer se nenhum outro estiver a fazê-lo. Assim sendo ele toma o controlo do meio de comunicação e envia os dados pretendidos. Se um outro dispositivo desejar enviar dados neste instante terá que esperar até o meio ficar novamente livre.

Fig. 4 - Método de comunicação CMSA.

De todos os protocolos, o X10 é, sem dúvida, um dos protocolos mais divulgados, e com maior sucesso, em todo o mundo. O X10 utiliza a rede eléctrica existente como meio de comunicação ao contrário de outros protocolos que obrigam a instalação de um barramento de transmissão próprio.

TDI - Transdutores domóticos inteligentes

Relatório Final 14/276

1.2 - O SISTEMA EIB (EUROPEAN INSTALLATION BUS)

1.2.1 - INTRODUÇÃO

O European Installation Bus é um sistema de gestão e controlo na área das instalações eléctricas para o accionamento de cargas, controlo ambiental e segurança. Permite regular, medir, comutar, prestar serviços de manutenção e monitorar em diferentes tipos de edifícios.

Esta tecnologia pode ser instalada em grandes edifícios, como por exemplo escritórios, escolas, hospitais e fábricas, assim como em residências domésticas, assegurando a monitorização e o controlo de funcionalidades e processos, tais como luzes, persianas, aquecimento, ventilação, ar condicionado, gestão de cargas, sinalização e alarmes.

Utiliza uma topologia livre e um sistema descentralizado (mais usual) ou centralizado com inteligência distribuída, baseado no protocolo de comunicações série CSMA/CA.

Sendo um sistema proprietário (não depende apenas de um fabricante) existem actualmente na Europa vários fabricantes de material eléctrico e electrónico que funcionam de acordo com o protocolo EIB.

Este sistema surgiu com o objectivo de ter uma implementação económica desde os pequenos edifícios até aos projectos de grande envergadura, em que a instalação do barramento de transmissão (bus) é estruturado hierarquicamente (usando acopladores de área e linha).

A instalação do bus é efectuada durante a instalação dos restantes circuitos para que este se encontre em paralelo com a nossa rede eléctrica de 220V.

Fig. 5. Barramento de transmissão (bus) e rede eléctrica

TDI - Transdutores domóticos inteligentes

Relatório Final 15/276

1.2.2 - DESCRIÇÃO FUNCIONAL

A alimentação dos dispositivos deste sistema é feita através do próprio meio de comunicação, que pode ser par entrançado ou a linha de alimentação 220V. O meio responsável pela troca de dados é isolado do meio que alimenta os dispositivos, ou seja, é necessário uma linha para a alimentação e outra para o envio de dados (fig. 5).

O segredo desta tecnologia reside no facto de serem usados circuitos simples nos interruptores e do consumidor estar conectado por um fio aberto ao barramento de transmissão. Estes interruptores são capazes de difundir a informação para o barramento de transmissão, o que quer dizer que, estes interruptores podem comunicar com um, indefinido, número de componentes (actuadores/sensores) independentemente da localização destes no edifício.

Componentes inteligentes, operando sobre uma arquitectura distribuída ou centralizada, são acoplados a esta comunicação entre os barramentos.

As conexões podem ter uma configuração (topologia) linear, em estrela, em anel, ou em árvore que permitem maior flexibilidade à aplicação.

Os sinais EIB podem ser transmitidos através de cabos entrelaçados e também sobre a rede eléctrica, embora esta ultima solução só seja aconselhável quando não existe outra alternativa devido à menor velocidade de comunicação que esta solução implica.

Os componentes responsáveis pela troca de sinais (troca de informação) podem ser programados para desempenhar determinadas funções em conjunto com outros componentes do sistema. Assim, qualquer um pode controlar os elementos constituintes do sistema (arquitectura descentralizada). Este tipo de arquitectura não requer, necessariamente, uma organização hierarquicamente estruturada nem dispositivos de supervisão da rede tornando a gestão do sistema bastante flexível.

Fig. 6 – Arquitectura descentralizada

TDI - Transdutores domóticos inteligentes

Relatório Final 16/276

Os componentes também podem ser controlados a partir de um PC (arquitectura centralizada), Fig. 7.

Fig. 7 – Arquitectura centralizada

O barramento EIB adapta-se facilmente ao tamanho da instalação e às funções a executar, podendo interligar mais de dez mil dispositivos.

Juntas (componentes, barramento de transmissão e/ou PC), formam a infra-estrutura funcional básica do sistema.

O sistema EIB designa os seus componentes como sensores e actuadores.

Os sensores (transmissores) são responsáveis por enviar informação (telegramas) para o sistema, condições para os elementos do sistema ou condições ambientais através do barramento de transmissão aos actuadores (receptores). Esta informação pode tomar apenas dois estados simples (on/off, open/close, yes/no) para medir (temperatura, tempo, velocidade do vento, luminosidade, etc...). Alguns exemplos de sensores são os interruptores de luzes, termóstatos e detectores de movimento.

Os actuadores (receptores) recebem a informação (telegramas) proveniente dos sensores e desempenham as suas respectivas (predefinidas) funções (especificas para cada actuador). Podemos dar como exemplos de funções; apagar luzes, baixar a temperatura e fechar obturadores. Como exemplos de actuadores podemos referir actuadores para luzes, válvulas, monitores de informação e motores de obturador.

Meio de transmissão

Par entrelaçado, linha de alimentação 220V, rádio frequência e infravermelhos são os vários tipos de meio suportados por esta tecnologia. Estes dois últimos tipos de meio requerem fontes de alimentação adicionais. Apesar disso o mais usual é o par entrançado.

TDI - Transdutores domóticos inteligentes

Relatório Final 17/276

Também é possível a interligação a qualquer outro sistema (RDIS, outros sistemas de gestão de edifícios) através de um dispositivo conversão – “gateway”.

A Fig. 8. apresenta um exemplo de instalação de barramento cablado

Fig. 8 – Barramento cablado

A topologia física do EIB é livre (p.e. linear, estrela, árvore, anel ou uma combinação destas) e consiste em secções de fio individuais, tão longos quanto o permitido pelos requisitos eléctricos (resistência e capacidade), designados por segmentos eléctricos. Estes tipos de topologia de segmentos eléctricos, que estão exemplificados na fig. 8, não requerem terminadores de rede.

Fig. 9 – As várias topologias possíveis do bus

Em cada linha de bus (segmento eléctrico) podem operar até 64 dispositivos. A tecnologia permite que dois segmentos sejam interligados através de um dispositivo repetidor, permitindo incluir até 4 segmentos eléctricos. Assim, podemos tirar partido de 256 (64x4) dispositivos por cada linha.

TDI - Transdutores domóticos inteligentes

Relatório Final 18/276

Os segmentos eléctricos são interligados através de acopladores de linha (AL) sendo possível interligar 15 linhas, formando assim uma área. Nestas circunstâncias, é possível interligar até 1007 dispositivos por área sem fazer uso de repetidores e 16 segmentos lógicos.

Também é possível interligar até 15 áreas usando os chamados acopladores de área (AA).

Podemos concluir que se forem usados repetidores, é possível interligar até um máximo 46080 (12 linhas, 4 repetidores por segmento e 15 AA) ou 57600 (15 linhas, 4 repetidores por segmento e 15 AA). Sem o uso de repetidores podemos ter até um máximo de 11520 dispositivos (caso 12 linhas e 15 AA) e 14.400 (caso15 linhas e 15 AA).

Fig. 10 – Estrutura da hierarquia do sistema EIB

As seguintes condições devem ser respeitadas:

• Cada segmento eléctrico (bus) não deve exceder os 1000m de comprimento;

• A máxima distância entre 2 segmentos eclécticos não deve exceder os 700m;

• O número máximo de dispositivos por segmento é 64;

• 12 a 15 segmentos por área;

• Um máximo de 15 áreas.

TDI - Transdutores domóticos inteligentes

Relatório Final 19/276

Transmissão de dados

Os dados são transmitidos simetricamente através de par entrelaçado, podendo também ser transmitidos sobre a rede eléctrica 220V. A transmissão de sinais é feita por meio da diferença de tensão entre os dois condutores do cabo.

A velocidade média de transmissão de dados é de aproximadamente 9,6kbps. Não é exigida nenhuma combinação de impedâncias.

A informação é modulada sobre baixa tensão (24VDC) e é separada da linha de alimentação dos dispositivos. Tem de existir, pelo menos, uma linha de alimentação por barramento (bus).

O acesso ao barramento é baseado no protocolo CSMA/CA (Carrier Sense Multiple Access with Collision Avoidanc).

O Quadro 1 apresenta as principais características da transmissão no sistema EIB.

Tipo de transmissão: Série

Método de transmissão: Banda base; Simétrica; Assíncrona

Velocidade de transmissão: 9.600bits por segundo

Formato de transmissão: A informação é modulada sobre a tensão contínua de 24V.

O “zero” lógico é representado por um impulso e o “um” lógico pela ausência de impulso.

Protocolo de acesso: CSMA/CA – “Carrier Sense Multiple Access with collision Avoidence”, com 4 níveis de prioridade (funções do sistema, alarme, prioridade alta de operação e prioridade baixa de operação).

Terminadores: Não necessita

Quadro 1 – Troca de dados codificados entre dispositivos EIB

Troca de dados e interfuncionamento

A comunicação entre um sensor (p.e. interruptor) e um actuador (p.e. lâmpada) obedece a uma sequência de operações (ilustrada na fig. 11). Segundo o protocolo EIB, o interruptor – inicialmente identificado pelo seu endereço físico (usado como endereço de destino durante a fase de inicialização do sistema, de diagnóstico e de programação; ou endereço de origem durante a operação normal do sistema) – comunica com a lâmpada

TDI - Transdutores domóticos inteligentes

Relatório Final 20/276

através do correspondente endereço de grupo (endereço de destino durante a operação normal do sistema). A transmissão de dados é feita através do envio de telegramas, com um único endereço de grupo, entre objectos de comunicação (caixas de correio). Do lado oposto, os objectos de comunicação podem subscrever diversos endereços de grupo, o que permite receber telegramas de diferentes origens. Isto significa que todos os dispositivos do barramento EIB subscritos com o endereço de grupo correcto (p.e. a nossa lâmpada) receberão a mensagem de comando do interruptor. Os dados de endereço especificam a área, o segmento eléctrico e os dispositivos aos quais a mensagem é endereçada.

Fig. 11 – Troca de dados codificados entre dispositivos EIB

O interfuncionamento entre os actuadores e sensores é dos principais objectivos que o protocolo EIB tem. Por esta razão existe uma pirâmide de interfuncionamento (fig. 12), onde são definidos os diferentes níveis de interfuncionamento.

Como bom exemplo deste processo poderemos referir a troca de correio, onde o objecto de comunicação é a caixa de correio e a funcionalidade é a acção que está escrita na carta.

Fig. 12 – Pirâmide de interfuncionamento entre actuadores e sensores

TDI - Transdutores domóticos inteligentes

Relatório Final 21/276

Em seguida é efectuada uma breve referência à pirâmide da figura anterior

• Primeiro patamar - a troca de dados tem de ser feita num formato comum (mesmo envelope). Este requisito é a base da comunicação, embora não garanta todo o interfuncionamento;

• Segundo patamar - o interfuncionamento mínimo é garantido quando a troca de variáveis for igualmente interpretada por todos os dispositivos (mesma semântica);

• Terceiro patamar - o próximo passo é partilhar funções comuns para garantir a compatibilidade nos dados de entrada e saída (mesmas regras gramaticais);

• Topo da pirâmide - para permitir que se consiga o mesmo e bem definido comportamento para diferentes dispositivos é necessário que o topo da pirâmide de interfuncionamento seja alcançado partilhando funcionalidades comuns (a mesma modalidade de expressão).

O EIB Interworking Standards (EIS) satisfaz estes requisitos e garante consistência no processamento das aplicações.

Alguns tipos de funções EIB

O quadro 2 apresentam algumas funções EIB.

O nome das funções é indicativo da respectiva aplicação, podendo cada função suportar várias aplicações. Por exemplo, o controlo do fluxo luminoso de um ponto de luz é realizado recorrendo à função EIB “Dimming”, mas esta função também poderá servir para controlo de aquecimento.

EIS N.º Função EIB EIS 1 Switching EIS 2 Dimming EIS 3 Time EIS 4 Date EIS 5 Value EIS 6 Scaling EIS 7 Drive control EIS 8 Priority EIS 9 Float value EIS 10 16-bit counter value EIS 11 32-bit counter value

Quadro 2 – Algumas funções EIB com o respectivo EIS

TDI - Transdutores domóticos inteligentes

Relatório Final 22/276

Troca de informação entre dispositivos

É conseguida através da transmissão de pacotes de dados com o formato descrito na figura 13.

Fig. 13 – Bloco de dados

Um telegrama, fig. 14, é composto por um conjunto de blocos de dados, contendo dados específicos para o encaminhamento da mensagem e dados sobre o evento que ocorreu. Um telegrama contém os seguintes campos:

• Controlo;

• Endereço de origem;

• Endereço de destino;

• Contador / comprimento;

• Dados de informação;

• Byte de verificação.

Fig. 14 – Estrutura de um telegrama EIB (comprimento medido em bits)

Endereçamento

Todos os dispositivos do barramento são identificados por um único endereço físico, como se ilustra na Figura 15. O endereço físico é composto por 16 bits, indicando a área, linha e número do dispositivo. O campo do endereço de origem contém sempre o endereço físico, que é usado como endereço de destino para operações de inicialização, programação e diagnóstico.

O endereço de grupo, representado na Figura 16, é uma ligação lógica entre dispositivos e é usado no modo de operação normal, em que o endereço de origem é o seu endereço físico e o endereço de destino é o endereço de grupo associado ao objecto de comunicação do dispositivo. As funções dos dispositivos (objectos de comunicação), pertencentes ao mesmo endereço de grupo, podem ser controladas por uma única

TDI - Transdutores domóticos inteligentes

Relatório Final 23/276

mensagem enviada pelo dispositivo de origem. No entanto, as funções podem pertencer a diversos grupos e podem ser activadas independentemente por qualquer dispositivo EIB do grupo. Deste modo, um sensor (p.e. interruptor) só pode transmitir um endereço de grupo, mas um actuador (p.e. lâmpada) pode receber vários. O endereçamento de grupo proporciona-nos flexibilidade de meios, permitindo adicionar dispositivos de uma forma muito simples, cujos objectos de comunicação ficam ligados ao respectivo endereço de grupo.

Fig. 15 – Transmissão e formato do endereço físico dos dispositivos EIB

TDI - Transdutores domóticos inteligentes

Relatório Final 24/276

Fig. 16 – Transmissão e formato do endereço de grupo em sistemas EIB

Inconvenientes

• É necessário a instalação de um barramento de dados (bus) que normalmente é o par entrelaçado. Isto implica que se uma casa quiser receber este sistema terá que fazer obras para ser possível uma instalação de novos fios que vão constituir o bus.

Vantagens

• Requer a instalação somente de um único barramento de controlo separado da rede eléctrica principal.

• Configuração descentralizada independente do tamanho da instalação.

• Reconfiguração simples das funções do quarto sem ser necessário a reinstalação de fios.

• Planeamento flexível e instalação simples.

• Todo o equipamento incorporado no sistema é capaz de comunicar com todos os outros existentes no barramento de transmissão.

TDI - Transdutores domóticos inteligentes

Relatório Final 25/276

• Redução da necessidade de usar 220V visto que muitos dos componentes que compõem o barramento de transmissão necessitam de baixa corrente e tensão.

• Expansão simples, até 14400 (64x15x15, sem recorrer ao uso de repetidores) componentes no barramento de transmissão.

• Redução do risco de curtos circuitos devido à redução da densidade de fios cablados na rede eléctrica.

• Múltiplas aplicações de componentes no barramento de transmissão; informação proveniente dos sensores está disponível em todos os pontos no barramento de transmissão; deste modo conseguem-se reduções de custos na duplicação de alguns dispositivos, na expansão do controle e na potencialidade funcional.

Podemos observar o que torna este sistema tão eficaz. Não é necessário um lote de vários sistemas cablados individuais para desempenhar as funções pretendidas (alarme, luzes, temperatura, obturadores de rolo) mas apenas um sistema individual pode constituir o lote.

TDI - Transdutores domóticos inteligentes

Relatório Final 26/276

1.3 - O SISTEMA LONWORKS

1.3.1 – INTRODUÇÃO

Lon ou LonWorks é uma topologia de rede que foi criada com dois objectivos iniciais:

• Primeiro para resolver o problema de controlo de sistemas, principalmente ao nível do controlo industrial, onde a existência de uma gestão centralizada seria de extrema importância;

• Segundo o de criar soluções de controlo baseadas em ligações ponto a ponto e lógica hierárquica de sistemas.

Num sistema de controlo centralizado (fig. 17), os sensores remotos são ligados a um microcontrolador que, por sua vez, envia impulsos a sistemas monitores e actuadores. Cada sistema de controlo centralizado é único, com requisitos próprios de entrada/saída e processamento. Os sistemas de controlo de grande porte, por serem mais complexos, podem ser repartidos em dois ou mais sistemas centralizados cujos microcontroladores centrais se comunicam continuamente.

Fig. 17 – Arquitectura centralizada

Esta topologia de rede “abre muitas portas” para a resolução de problemas de arquitectura, construção, instalação, controlo e manutenção de redes.

Actualmente a topologia de rede LonWorks é uma plataforma proprietária aberta. Cada nó da topologia inclui computação local, fontes próprias e pode ser ligado a diferentes e diversos dispositivos, nomeadamente a, sensores e actuadores.

Consequentemente, um controlo centralizado torna-se exageradamente complexo, caro e, possivelmente, lento.

TDI - Transdutores domóticos inteligentes

Relatório Final 27/276

Estrutura hierárquica típica (mais antiga) do sistema.

Esta estrutura está representada na figura 18. Aqui podem ser encontrados os controladores, que podem conter alguns componentes pertencentes ao sistema LonWorks, conectados à rede de dispositivos e isolados (device buses ou device networks).

A função dos controladores consiste em controlar o acesso aos sensores e actuadores, obedecendo a uma certa ordem de prioridade, proporcionando assim uma distribuição de inteligência pelos dispositivos em campo e o acesso a qualquer ponto da rede.

Por vezes as gateways comunicam sobre uma rede aberta (control bus) mas continuam a ser um sistema proprietário fechado.

Mesmo quando implementado com dispositivos LonWorks esta arquitectura não consegue tirar total partido deste sistema. Utilizando esta arquitectura em dispositivos LonWorks trás, tipicamente, limitações a nível de tomadas de decisões, de responsabilidades e uma reduzida interacção com outros dispositivos dispostos em outras partes da hierarquia.

Até aos controladores de supervisão, o sistema continua a ser fechado. Estes dispositivos são os responsáveis por assegurar a maioria das relações de controlo entre os dispositivos de E/S, unidades terminais com os outros controladores de supervisão. Estes dispositivos também são utilizados como gateways para que a informação, passe para outro meio de transporte.

Os controladores de sistema são frequentemente usados para fornecer um trajecto de conectividades até um outro barramento proprietário ou, para incorporar novo equipamento do sistema. Cada sistema tem ferramentas de rede que permitem operações de configuração e manejamento.

Fig. 18 – Estrutura hierárquica típica

Nesta arquitectura encontramos limitações a nível de tomadas de decisão, de responsabilidades, e grandes limitações de interacção com os outros dispositivos.

TDI - Transdutores domóticos inteligentes

Relatório Final 28/276

Esta arquitectura não é a solução de controlo mais rentável por diversas razões:

• É desnecessariamente complexa;

• É proprietária;

• Não é possível a comunicação com qualquer ponto, a qualquer hora, de qualquer local de rede.

Deste modo esta arquitectura de sistema hierárquica torna-se pesada e cara.

Quando implementada em redes LonWorks até à ultima camada o controlo arquitectural das múltiplas camadas faz com que o sistema seja composto por um conjunto de redes LonWorks isoladas. Esta rede irá conter, relativamente, poucas ligações ponto a ponto entre dispositivos.

Os dispositivos LonWorks estão limitados a dividir e partilhar dados directamente com outros dispositivos apenas se estiverem no mesmo local de rede.

O nível de controlo controller level é manejado pelo software contido nos controladores de supervisão, em vez de ser manejado por software que coordene transferências de informação, como devia ser no caso de um sistema proprietário aberto.

Assim surgem como novos objectivos:

• Distribuir interoperabilidade e implementar guidelines;

• Transformar o sistema num sistema de características abertas;

• Fornecer sustentação técnica e ferramentas de desenvolvimento;

• Examinar a hipótese de tornar o sistema num sistema standard.

TDI - Transdutores domóticos inteligentes

Relatório Final 29/276

1.3.2 - DESCRIÇÃO FUNCIONAL

Actualmente esta tecnologia (LonWorks) está a proporcionar uma nova era para os sistemas de controlo distribuído, em que o fabricante ou integrador pode implementar, de forma rápida e fácil, redes de dispositivos inteligentes, interligados por um ou mais meios de comunicação, comunicando entre si usando o protocolo Lontalk®.

Sucintamente, essa tecnologia baseia-se na conexão dos elementos que compõe um sistema de automação através de um cablamento comum, formando uma rede de dispositivos, que podem ser acedidos individualmente, utilizando mensagens padronizadas por um protocolo (fig. 19).

Fig. 19 – Arquitectura mais distribuída da nova tecnologia LonWorks

Uma série de vantagens, comuns a inúmeras aplicações, impulsiona o movimento rumo aos sistemas de controlo com inteligência distribuída, pois esses sistemas:

• Reduzem os custos iniciais de desenvolvimento dos projectos, além de permitir que o mesmo sistema de comunicação seja usado em muitas aplicações diferentes;

• Facilitam a expansão e reconfiguração;

• Proporcionam maior flexibilidade, seja quanto ao tamanho, configuração ou aplicação do sistema;

• Diminuem os custos de instalação, poupando ou eliminando cablagem;

• Viabilizam aplicações de difícil materialização com os sistemas centralizados;

• Permitem que produtos e sistemas antes incompatíveis possam inter-operar;

TDI - Transdutores domóticos inteligentes

Relatório Final 30/276

• Melhoram a operação, administração e confiabilidade do sistema como um todo (o mau funcionamento de uma parte não implica, necessariamente, no mau funcionamento de todo o sistema).

A nova tecnologia LonWorks® é formada por uma rede de dispositivo de controlo inteligentes, chamados “nós” (podem ser detectores de movimento, detectores de proximidade, relés, chaves...), que comunicam usando um protocolo comum. Esses dispositivos são dotados de alguma capacidade de processamento, o que aliado à conexão dos dispositivos em rede (Fieldbus), pode levar a uma solução onde os próprios dispositivos troquem mensagens entre si e o controle do sistema de automação seja da responsabilidade da própria rede de dispositivos e não de um elemento centralizador (CLP, PC). Cada “nó” da rede, por sua vez, contém inteligência embutida capaz de implementar o protocolo e desempenhar todas as funções de controlo. Além disso, cada “Nó” inclui um transceiver com o meio físico, que conecta o microcontrolador do “nó” ao meio de comunicação e a sua própria fonte de alimentação (5V).

O Barramento é chamado de canal. Os canais podem ser interligados recorrendo ao uso de routers ou pontes (bridges). A rede completa é denominada por domínio (domain), fig. 20.

Fig. 20 – Rede de dispositivos

Este sistema não é sincronizado e por isso, é possível que vários dispositivos possam tentar comunicar ao mesmo tempo.

A figura 21 mostra o diagrama de um “nó” individual, num sistema de controlo com inteligência distribuída. O “nó” requer um microprocessador ou microcontrolador, interfaces de E/S para sensores e actuadores, protocolo de comunicação e um transceiver para o meio de comunicação considerado.

Adicionalmente, a rede de controlo pode requerer o desenvolvimento de routers e de interfaces de rede.

TDI - Transdutores domóticos inteligentes

Relatório Final 31/276

Fig. 21 – Esquema de um nó individual para uma configuração distribuída

O coração da tecnologia LonWorks é o chip Neuron, fig. 22, um sofisticado componente VLSI.

Esse super chip baptizado por Neuron® incorpora comunicação, controle, gestão (scheduling) e suporte de E/S. Ele foi o ponto de partida para o desenvolvimento de uma lista completa de produtos que inclui ferramentas de hardware e software – incluindo, entre outros, estação de desenvolvimento, analisador de protocolo, emulador, placas diversas – e produtos OEM que o cliente usaria em sua produção ou instalação, como transceiver, módulo de controle, routers, pontes e adaptadores serie.

Fig. 22 – Estrutura em blocos de um Chip Neuron

O quadro 3 resume, de modo muito sintetizado, a evolução desta tecnologia desde 1973.

TDI - Transdutores domóticos inteligentes

Relatório Final 32/276

1973 Microprocessador

1985 Microcontrolador

1993 Chip Neuron

Características Processamento geral

Controlo embutido

Controlo distribuído

Recursos Processador Processador memória E/S simples Interface serial

3 Processadores Memória E/S multidimensional Interface de rede

Software Nenhum Nenhum Modelo OSI implementado com as 7 camadas Sistema operacional (firmware)

N.º limite de “nós”

Não aplicável dezenas Milhares

Linguagem de programação

C (típica) Assembler (típica)

Quadro 3 – Evolução tecnológica do sistema Lon

Como o protocolo LonTalk, que atende todas as sete camadas do modelo de referência OSI, é implementado em ROM (onde pode ser programado em linguagem C orientada a eventos e objectos) e hardware no chip Neuron, e assim todo os “nós” de uma rede LonWorks são interoperáveis, suportando assim a comunicação distribuída.

A troca de informação entre os dispositivos é efectuada a partir da troca de mensagens sem haver necessidade de se conhecer a topologia da rede, o nome, o endereço ou as funcionalidades dos outros dispositivos. Para se conectar à rede é necessário incluir apenas um transceiver adequado, tornando viável que a tecnologia seja integrada ao dispositivo sem que haja o aumento de tamanho, permitindo a todos os “nós” a possibilidade de passar instruções entre si.

Os transceivers também merecem destaque pela variada gama de opções e velocidades de comunicação: Par entrelaçado (1.25Mbps), Power link (par entrelaçado com alimentação embutida - 78 Kbps), Power line (rede eléctrica - 10 Kbps), Cabo Coaxial (1.25 Mbps) , Fibra Óptica (1.25 Mbps) ou RF (4.8 Kbps).

Através dos dispositivos de E/S dos “nós”, os sinais recebidos podem ligar ou desligar actuadores, ou ler sensores e informar a leitura na rede. Por exemplo, após receber mensagem do “nó” do sistema de detecção de incêndio, o “nó” que controla o elevador pode envia-lo automaticamente para o andar desejado.

TDI - Transdutores domóticos inteligentes

Relatório Final 33/276

Meio de transmissão e transmissão de dados

Os recursos disponíveis para que a tecnologia LonWorks possa comunicar através de qualquer meio são a rede eléctrica (portadora), o par entrelaçado, a radiofrequência, os infravermelhos, a fibra óptica e o cabo coaxial.

As mais exploradas actualmente são a rede eléctrica e o par entrelaçado. Estes meios proporcionam 42V diferenciais (+21 Volt) à rede. A potência total extraída pela rede não excede os 40W.

Os “nós’ podem ser combinados para encaminhar mensagens de um meio para outro (p.e. da eléctrica para o par trançado). O resultado é uma rede de controlo totalmente integrada, que pode associar produtos de vários fornecedores.

A topologia usada é livre sendo determinada na fase de instalação, podendo ser implementada em linha, em estrela, em árvore ou em anel.

O quadro 4 sintetiza diferentes características associadas a diferentes tipos de meios de transmissão.

Tipo de canal Meio físico Bit rate Nº máximo de

dispositivos Distância máxima

TP/XF-1250 par entrelaçado 1.25Mbps 64 125m

PL-20 rede eléctrica 5.4Kbps Depende do meio ambiente

Depende do meio ambiente

IP-10 sobre ip determinada pela rede ip

determinada pela rede IP

determinada pela rede IP

TP/FT-10

Topologia livre ou por barramento

78Kbps 64-128 500m (livre) 2200m (barramento)

Quadro 4 – Características referentes a diferentes meios de transmissão

O meio que torna o sistema mais lento é a linha eléctrica que limita a velocidade a 2kbps.

A informação transmitida pelo bus é descrita sob a forma de frames e é denominada por MAC (Media Access Control), Protocol Data Units ou MPDUs na tecnologia LonWork. Um MPDU é constituído por:

Fig. 23 – Contituição de um MPDU (“frame”)

O BitSync e o ByteSync servem para avisar a todos os nós que sincronizem os seus relógios de recepção. O campo L2Hdr é usado pelo Mac layer do protocolo. De seguida é transmitido um campo de dados chamado Network Protocol Data Unit ou NPDU. O frame é terminado com o envio de um campo de 16 bit CRC para detecção e correcção de erros. O campo NPDU pode ser dividido nos seguintes semi-campos:

TDI - Transdutores domóticos inteligentes

Relatório Final 34/276

Fig. 24 – Campo NPDU

O semi-campo version define a versão do protocolo. Format define o tipo de formato para o semi-campo Address e Protocol data unit.

Dependendo do semi-campo format, o semi-campo address pode conter um ou mais dos seguintes endereços: source address, destination address, subnet ID, Destination SubNet ID, Neuron ID.

O Protocol Data Unit (PDU) contém os dados actuais para comunicar com os outros dispositivos.

A comunicação obedece ao protocolo CSMA (Carrier Sense Multiple Access).

Endereçamento

O algoritmo de endereçamento define qual o pacote que é encaminhado de um dispositivo para um ou vários dispositivos. Estes pacotes podem ser enviados para um único dispositivo, para um qualquer grupo de dispositivos ou para todos os dispositivos. Para suportar uma rede de dispositivos que contêm entre dois a dezenas de milhares de dispositivos, o protocolo LonWorks suporta vários tipos de endereços. Desde o simples endereço físico até endereços que designam vários grupos de dispositivos.

Os diferentes tipos de endereços são:

O Endereço físico (physical address) onde todos os dispositivos Lon contêm um único identificador de 48 bit chamado Neuron ID. Este identificador é tipicamente associado na fase de fabrico de um dispositivo e nunca sofre alterações até ao fim da sua vida.

Endereço de dispositivo (device adress) onde um dispositivo Lon é associado um device adress quando este dispositivo é instalado na rede de dispositivos Lon. O device address é usado em vez do physical address porque consegue garantir melhor eficiência na parte do encaminhamento de mensagens e simplifica a reposição de dispositivos com falhas. A ferramenta de instalação da rede mantém uma base de dados dos device address já existentes na rede.

Este endereço assenta sobre três componentes:

• O ID de domínio (domain ID),

• O ID da sub rede (subnet ID)

• O ID do nó (node ID).

TDI - Transdutores domóticos inteligentes

Relatório Final 35/276

O primeiro (domain ID) identifica um conjunto de dispositivos que podem interagir entre si. Podemos ter até 32000 dispositivos num domínio.

O subnet ID identifica um conjunto, que pode ir até 127 dispositivos inseridos num único canal ou num conjunto de canais conectados por repetidores. Este endereço é usado para encaminhar, de forma eficiente, os pacotes na rede. Pode suportar até 255 sub redes por domínio.

O node ID identifica o dispositivo individual contido numa sub rede.

Endereço de grupo (group address)

Um grupo é um conjunto lógico de dispositivos inseridos num domínio. Ao contrário da sub rede, os dispositivos estão agrupados em conjunto sem dar importância à sua localização física no domínio. Podemos usar qualquer número de dispositivos, no grupo, quando uma mensagem de não reconhecimento (unacknowledged messaging) for utilizada.

Caso se usem mensagens de reconhecimento (acknowledged messaging) os grupos são compostos por um máximo de 64 dispositivos. Os grupos são uma forma eficiente para optimizar a largura de banda da rede para endereçar pacotes a múltiplos dispositivos. Podemos ter até 256 grupos num domínio.

Endereço de transmissão (broadcast address)

Este endereço tem como responsabilidade a identificação de todos os dispositivos da sub-rede, ou de todos os dispositivos num domínio. É um método eficiente para troca de informação (comunicação) entre muitos dispositivos, e por vezes é usado em vez do endereço de grupo para conservar o número limite disponível neste endereço.

Todos os pacotes LonWorks transmitidos sobre a rede contêm o endereço de dispositivo do dispositivo que transmite (source address) e o endereço dos dispositivos receptores (destination address), que também pode ser o endereço físico, de dispositivo, de grupo ou de transmissão.

Múltiplos domínios são usados se o número de dispositivos exceder o limite previsto do domínio ou se existir um desejo de separar os dispositivos para eles não interagirem. Isto é possível para dois ou mais sistemas LonWorks independentes coexistam no mesmo canal físico, contando que cada sistema tenha um único domínio ID.

Os dispositivos neste sistema respondem só aos pacotes que lhes foram devidamente dirigidos, ou seja, aos que correspondem ao seu domínio ID e não querem nem podem saber dos pacotes endereçados com outros domínios ID.

Dispositivos também respondem aos pacotes endereçados com o seu próprio endereço físico, o que é normalmente sabido a quando da instalação das ferramentas correspondentes à rede. Quando a rede física é dividida, o tempo de resposta de toda a rede vai ser afectada devido a um crescente aumento de número de pacotes, por isso é fundamental, coordenar todo o design da rede.

TDI - Transdutores domóticos inteligentes

Relatório Final 36/276

Serviços de mensagens

O protocolo LonWorks oferece três tipos básicos de mensagens de distribuição de serviços e também suporta mensagens de autenticação. Uma rede optimizada poderá usar frequentemente todos estes serviços de mensagens. Estes serviços permitem uma conjugação entre eficiência, segurança e seriedade. As mais importantes são:

• Acknowledged Messaging - proporciona o reconhecimento para término de comunicação. Quando se usam estas mensagens elas são transmitidas para um dispositivo ou para grupos constituídos, por um máximo, de 64 dispositivos esperando-se de seguida uma mensagem individual destes dispositivos de recepção. Se o reconhecimento (Acknowledged Messaging) não for recebido ao fim de um certo tempo, o emissor cancela a negociação de transmissão. O número de “cancelamentos” e o tempo de espera são configuráveis.

Repeated Messaging - mensagem que é enviada para um dispositivo ou para um grupo, composto por qualquer número de dispositivos, repetidas vezes. Normalmente, este serviço é usado em vez do Acknowledged Messaging pois neste caso não será necessário incluir o cabeçalho e o atraso de espera pela resposta. Isto é especialmente importante quando a informação é difundida (broadcasting information) para um vasto grupo de dispositivos, onde a mensagem de reconhecimento iria dar origem a uma tentativa de resposta em simultâneo por parte de todos os receptores.

Unacknowledged Messaging - esta mensagem é enviada uma vez para um dispositivo ou grupo de indefinidos dispositivos sem ser esperada qualquer resposta. Esta mensagem/serviço tem o cabeçalho mais pequeno e é tipicamente o serviço mais usado.

Authenticated Service - permite determinar aos dispositivos receptores de uma mensagem se o emissor está autorizado a enviar essa mensagem. Desta maneira, é possível controlar a autenticação não autorizada de dispositivos. Isto é feito na fase de instalação onde é implementada uma distribuição de chaves de 48-bit nos dispositivos.

Vantagens

• Versatilidade na especificação de topologias de ligação (possibilitando redundância, por exemplo), facilidade de instalação física do sistema (não é o mais fácil de instalar de todos os sistemas);

• Diminuição dos custos e viabilização das implantações.

TDI - Transdutores domóticos inteligentes

Relatório Final 37/276

Atributos Benefícios O que LonWorks oferece

Um protocolo de comunicação aberto, robusto e realizável

Assegura interoperabilidade básica entre dispositivos de diferentes fabricantes desde que seja usado o mesmo protocolo

Protocolo LonTalk

Circuitos inteligentes contêm o protocolo e as aplicações dos dispositivos.

Baixo custo em recursos adicionais. Fabrico concentra-se na aplicação e não nos problemas de comunicação.

Neuron chip Transceivers

Operações de rede para instalação, configuração, manutenção, monitorização e controlo

Administração da rede é uniforme, através das ferramentas e das plataformas

Arquitectura LNS

Infra-estruturas de dispositivos (routers, repetidores, PC)

Escalonamento Routers core module

Interoperabilidade compreensiva, orientação de fabrico e integradores do sistema

Interoperabilidade aberta e verdadeira

LonMark interoperability association LonMark interoperability guidelines

Quadro 5 – Vantagens que o sistema Lon oferece

Desvantagens

• Interoperabilidade dos dispositivos credenciados pelo LonMark. Põe-se em dúvida a padronização das variáveis de rede (SNVT's) entre os diferentes fabricantes, assim como a possível existência de diferentes soluções para o mesmo problema, o que faz com que um dispositivo não seja imediatamente substituível por um similar de outro fornecedor. Também em relação às SNVT's, existem críticas à sua abrangência, que, por ser limitada, faz com que muitos dispositivos precisem necessariamente ser construídos de forma não padronizada, deixando então de ser interoperável.

• A documentação acerca do funcionamento deste sistema é bastante complexa e pesada, não sendo de fácil compreensão por parte dos que a querem desenvolver.

• As ferramentas de desenvolvimento são caras, particularmente a LonMaker e a Node Binding software.

• A velocidade de comunicação embora possa atingir até 1.25 Mbps, muitos meios de comunicação disponíveis têm velocidades baixas, o que classifica a rede

TDI - Transdutores domóticos inteligentes

Relatório Final 38/276

Lontalk como insuficiente para algumas aplicações, principalmente aquelas com alto tráfego de informações e necessidade de resposta em tempo real.

Actualmente o LonWorks tem a seu favor um grande número de fornecedores que fornecem uma vasta diversidade de hardware e software, contribuindo para o seu desenvolvimento.

A empresa criadora desta topologia (a Echelon) tem desenvolvido aproximações, na sua topologia LonWorks, que permitem maior flexibilidade com o objectivo de obter um elevado grau de simplicidade na sua implementação..

Como já foi referido, esta topologia de rede é uma plataforma proprietária aberta, que embora dependa muito das opções de quem detém os seus destinos, consegue oferecer a garantia inerente à defesa dos interesses das empresas que a adoptam.

TDI - Transdutores domóticos inteligentes

Relatório Final 39/276

1.4 - O SISTEMA X-10

1.4.1 - INTRODUÇÃO

O X-10 foi, inicialmente, a tecnologia mais requisitada pelos amadores ligados à área de automatização de habitações e mesmo a mais utilizada nas instalações domóticas caseiras.

Hoje em dia a abundância ainda permanece, mas em maior densidade nos EUA.

Foi originalmente introduzido em 1978 com o objectivo de ser instalado em mais de 4 milhões de casas por todo mundo.

Este sistema foi projectado primariamente para funcionar como sistema de controlo electrónico de iluminação e limitado a seis comandos (ON, OFF, DIM, BRIGHT, ALL LIGHTS ON e ALL LIGHTS OFF).

O sistema X-10 é uma linguagem de comunicação que permite que produtos compatíveis entre si comuniquem, utilizando para tal a rede eléctrica existente nas casas.

É um sistema não proprietário aberto, o que nos proporciona uma grande variedade de opções, nomeadamente a escolha de produtos, de fabricantes e de fornecedores.

Este protocolo é actualmente dos mais utilizados no mundo (principalmente em pequenas habitações), devido à sua simplicidade, estando também bastante desenvolvido.

Permite controlar várias funcionalidades e processos, tais como luzes, persianas, aquecimento, controlo de acessos, ventilação, ar condicionado, sinalização e alarmes, tornando possível a automatização e controlo de uma residência doméstica.

Fig. 25 - Casa inteligente

TDI - Transdutores domóticos inteligentes

Relatório Final 40/276

Utiliza também uma topologia livre, como os dois sistemas apresentados anteriormente, e normalmente usa um sistema descentralizado sendo, também possível usar um elemento centralizador (PC) para tornar o sistema num sistema de características centralizadas.

O envio de dados (bits) é realizado em cada passagem da tensão eléctrica alternada por zero (“zero-crossing”). A amplitude dessa tensão é 110V (EUA) ou 230V (Europa), dependendo do país onde é utilizado.

Este protocolo de comunicação é usado essencialmente por aplicações eléctricas. Está criado de modo a que as trocas de informação entre transmissores (normalmente sensores) e receptores (normalmente actuadores, como p.e. lâmpadas, válvulas, alarmes, etc.) X-10 sejam realizadas através de condutores standard, normalmente os condutores da rede eléctrica de nossa casa.

1.4.2 - DESCRIÇÃO FUNCIONAL

A instalação e uso desta tecnologia são bastante simples. Basta colocar um transmissor X-10 numa tomada, situada num qualquer local da casa, e enviar comandos próprios desta tecnologia para o receptor X-10. Este terá que estar também ligado a uma tomada situado num qualquer ponto da casa (figura 27).

A alimentação dos dispositivos deste sistema é feita através do próprio meio de comunicação. Cada dispositivo contém um transformador responsável por transformar o sinal proveniente da rede eléctrica 220VAC num outro sinal de 5VDC para se conseguir alimentar o PIC e outros circuitos integrados que normalmente funcionam a tensões baixas e com correntes contínuas.

Fig. 26 – Instalação de dispositivos X-10

Outros símbolos que podem ser encontrados são:

Fig. 27 – Outros símbolos identificadores de módulos

TDI - Transdutores domóticos inteligentes

Relatório Final 41/276

Este protocolo de comunicação tira partido do facto de serem utilizados circuitos integrados nos módulos transmissores e receptores, proporcionando-lhes alguma inteligência e de ser possível adicionar um novo módulo ao sistema, a qualquer momento e em qualquer tomada.

Estes interruptores são capazes de difundir a informação para a rede, o que quer dizer que, podem comunicar com um, número indefinido de componentes (actuadores/sensores) independentemente da localização destes na casa.

As conexões podem ter uma configuração (topologia) linear, em estrela, em anel, ou em árvore que permitem maior flexibilidade à aplicação. A dimensão do sistema vai depender das condições específicas de cada casa. Normalmente a distância máxima que assegura uma comunicação sem grandes problemas, sem recorrer a pontes ou repetidores de sinal, é inferior a 185m devido a grandes ruídos existentes na própria rede de comunicação resultando daí as esperadas perdas de dados.

Meio de transmissão

O meio de transmissão mais utilizado por esta tecnologia, é sem dúvida, a própria rede eléctrica das nossas casas. Existe também a possibilidade de ser utilizada a transmissão por radiofrequência (wireless), existindo um protocolo específico para tal.

Transmissão de dados

Os dados são transmitidos de acordo com o protocolo X-10 (apresentado mais à frente, na secção 1.6.2 ) sobre a própria rede eléctrica da casa.

A informação (dados) é modulada no próprio sinal eléctrico. Cada passagem da tensão eléctrica alternada por zero (denominado zero-crossing) transporta consigo um bit de informação (um 1 ou um 0).

Uma mensagem é composta por um endereço e por um comando. O endereço é enviado em duas partes. Na primeira metade do endereço é enviado o House code composto por 4 bits, e na segunda metade é enviado o Unit code composto por 5 bits, sendo o ultimo bit reservado para desempenhar um comportamento funcional, que neste caso toma o valor 0 lógico visto estarmos na presença de um código para endereço.

Este último código de 5 bits é denominado por function code (ou key code) visto poder servir para enviar a segunda parte de endereços ou os comandos.

O envio de comandos é efectuado, também em duas partes. A primeira é igual à primeira parte do endereço House code e na segunda parte é enviado o function code referente a um determinado comando. O function code é composto por 5 bits com o último bit com valor lógico 1, visto estarmos na presença de um comando (Comand code).

A velocidade de transmissão que este sistema nos oferece é de 50bps e não tem qualquer tipo de correcção ou detecção de erros sofisticada, não possuindo assim qualquer tipo de protecção contra colisão de informação e detecção de portadora.

Os circuitos integrados nos módulos X-10 fazem dele, não um microcontrolador mas um módulo independente que é ligado à rede e fica conectado automaticamente ao sistema com entradas e saídas paralelas.

TDI - Transdutores domóticos inteligentes

Relatório Final 42/276

Troca de dados e interfuncionamento e Endereçamento

Os transmissores enviam comandos tais como turn off ou dim precedidos pela identificação (endereço) da unidade receptora, que vai ser responsável por executar esse comando.

Os comandos são difundidos (enviados, ao mesmo tempo, para todos os receptores) e cada receptor que contém uma identificação de unidade, reage apenas aos comandos que lhes são endereçados.

Usando selectores ou teclas simples, existentes no próprio módulo ou produto, atribui-se a cada módulo um dos 256 endereços possíveis. Este endereço é composto por um Unit code podendo tomar um valor entre 1 e 16, e por um House code, que toma uma das letras de A a P.

Fig. 28 – Selectores para atribuição de endereços X-10

Se desejar que dois ou mais produtos reajam aos comandos X-10 ao mesmo tempo atribui-se o mesmo endereço a estes produtos. Todos os produtos X-10 compatíveis podem ser combinados e misturados livremente para poderem desempenhar as diferentes e inúmeras funcionalidades pretendidas pelos utilizadores.

Alguns tipos de comandos

O quadro 6 apresenta alguns comandos X-10. O quadro contêm o nome dos comandos e o código binário desse comando. O nome do comando especifica a função que desempenha.

O último bit do código de comando é um bit de funcionalidade que toma o valor 1 caso se trate de um comando e 0 se for um endereço (Unit code).

TDI - Transdutores domóticos inteligentes

Relatório Final 43/276

Quadro 6 – Comandos X-10

Utilização

O sistema X-10 aprecia o uso difundido dos dispositivos. Não é um sistema de características compatíveis para ser implementado em situações industriais ou de edifícios.

Desvantagens

Os problemas que podem ser encontrados são essencialmente na parte da comunicação, em que a solução é implementada recorre ao uso de bridges ou de amplificadores de sinal.

Na maioria das vezes este sistema funciona sem quaisquer problemas. Contudo e porque este sistema utiliza a rede eléctrica, para trocar comandos, podem surgir dificuldades em duas situações.

A primeira ocorre quando um dispositivo que gera muito ruído na rede eléctrica. Este ruído é essencialmente gerado por motores (utilizados nos diferentes tipos de electrodomésticos; p.e. aspirador, secador, varinha mágica) e por uso de aparelhos de electrónica avançada (p.e. algumas ecrãs gigantes, fontes de alimentação com selectores). Mas este problema é facilmente ultrapassado devido à existência de módulos que filtram este ruído.

A segunda situação acontece quando o transmissor X-10 está numa fase da rede e o receptor está na outra. Normalmente recorre-se ao uso de um simples módulo acoplador de fase chamado SignaLinc.

TDI - Transdutores domóticos inteligentes

Relatório Final 44/276

Actualmente a informação disponível não está completamente controlada e aprovada, visto este sistema, ser não proprietário.

Vantagens

Os produtos X-10 são dos mais requisitados e são os mais usados em todo mundo. Estima-se que só nos Estados Unidos da América existam mais de 10 milhões de casas que possuem este sistema. Isto deve-se ao facto de existirem inúmeras vantagens neste sistema quando comparado com outros.

Fig. 29 – Exemplo de uma rede X-10

TDI - Transdutores domóticos inteligentes

Relatório Final 45/276

As mais importantes são:

• Barato;

• Não é necessário nada mais para além da rede eléctrica, o que é perfeito para manutenção e substituição de produtos;

• Grande facilidade de instalação;

• Grande variedade de produtos (mais de 100 produtos compatíveis);

• Controlo sobre 256 dispositivos individuais ou um maior número se associarmos a um endereço mais que um dispositivo;

Tem vindo a ser desenvolvido desde à 20 anos.

A Fig. 29 apresenta um esquema básico de uma instalação X-10 que, decerto, contribui para uma melhor compreensão das aplicações, benefícios e comodidades que este sistema nos pode oferecer.

TDI - Transdutores domóticos inteligentes

Relatório Final 46/276

1.5 - PRINCIPAIS DIFERENÇAS ENTRE X10, EIB E LONWORKS

Enunciam-se em seguida as principais diferenças entre os sistemas EIB, LonWorks e X-10. Apesar da existência de várias diferenças entre EIB e LonWorks, estes sistemas diferem muito mais do sistema X-10 do que entre eles.

Os sistemas EIB e X-10 permitem uma grande variedade de opções, nomeadamente a escolha de produtos, de fabricantes e de fornecedores, pois são sistemas não proprietários abertos.

Visto serem de fácil dispersão tecnológica proporcionam uma adesão de novos fabricantes e fornecedores, contribuindo, assim, para um aumento constante da base de sustentação do protocolo e oferecendo novas garantias de qualidade aos clientes finais.

O sistema LonWorks, como sistema proprietário até pode ser uma boa opção a nível técnico mas, devido ao facto de que na Europa a quota de mercado destes sistemas é reduzida, traz algumas limitações a nível de escolha de fornecedores, resultando daí esperadas restrições nas alternativas quando se pensa na expansão ou em futuras manutenções.

As principais diferenças entre estes 3 sistemas são:

Modo de transmissão da informação

• EIB - utiliza um barramento de transmissão próprio (Bus), com excelentes garantias de fiabilidade de transmissão, mas têm de ser suportados maiores custos na instalação. Explora pouco mais meios de comunicação para além do par entrelaçado ou a rede eléctrica. Sendo o primeiro instalado paralelamente com a rede eléctrica. Consegue instalações de grandes dimensões (1000m de comprimento máximo de barramento + 700m de distância máxima entre barramentos, podem ser interligados até 15 barramentos e 15 áreas).

• LonWorks - pode utilizar diferentes meios de transmissão num sistema: par entrelaçado, rede eléctrica, RF, infravermelhos, fibra óptica e o cabo coaxial. Actualmente o mais usado é o par entrelaçado ou a rede eléctrica. Permite criar sistemas de grande dimensão, devido à grande diversidade de endereços, podendo alcançar os 2200m de comprimento máximo do barramento.

• X-10 - utiliza os condutores de potência da própria rede eléctrica, reduzindo, logo à partida, os custos de instalação, mas tornando mais difícil a possibilidade de estabelecimento de instalações mais exigentes como edifícios de uso colectivo ou edifícios de elevada complexidade tecnológica (a partir dos 185m começa a surgir incapacidades de comunicação).

TDI - Transdutores domóticos inteligentes

Relatório Final 47/276

Endereçamento/protocolo

• EIB - envia a mensagem (pacote de dados) para um dispositivo; para um grupo de dispositivos ou para todos os dispositivos. Utiliza um sistema composto por acopladores de linha (que interligam os segmentos eléctricos contidos numa área) e de área (que interligam as áreas) para endereçar as mensagens. A informação é modulada e conduzida sobre 24VDC. O envio de informação é bastante mais complexo, em relação ao sistema X-10, devido ao facto de o seu protocolo obedecer ao modelo OSI que é composto por 7 camadas. A transmissão dos dados é efectuada de acordo com o protocolo de comunicações série – CSMA/CA.

• LonWorks - tal como no sistema EIB, o LonWorks envia a mensagem para um dispositivo; para um grupo de dispositivos ou para todos os dispositivos. Utiliza routers ou pontes para direccionar as mensagens. A informação é modulada e conduzida sobre 42V diferenciais (±21V). O envio de informação é bastante mais complexo, em relação ao sistema X-10, devido ao facto do protocolo obedecer ao modelo OSI que é composto por 7 camadas. A transmissão dos dados é efectuada de acordo com o protocolo de comunicações série – CSMA/CA.

• X-10 - envia a mensagem por broadcast, ou seja, para todos os dispositivos do sistema. Só os dispositivos que têm o endereço que a mensagem específica é que a recebem. Transmite os dados sobre a própria rede eléctrica – 220VAC, 50Hz. Não necessita de dispositivos adicionais para distribuir as mensagens a não ser os interruptores contidos nos próprios dispositivos. Protocolo de comunicação bastante mais simples e próprio.

Velocidades de transmissão

• EIB - a velocidade média de transmissão é de 9,6Kbps.

• LonWorks - pode atingir um máximo de 1,25Mbps e um mínimo de 2kbps. Tudo depende do meio usado.

• X-10 - não ultrapassa os 50bps (devido à frequência da rede ser 50Hz).

Nº máximo de dispositivos:

• EIB - se só forem usados acopladores de linha o sistema chega facilmente a atingir os 1000 dispositivos por área. Se, para além destes também forem usados acopladores de área e repetidores o sistema pode chegar a atingir os 57.600 dispositivos.

• LonWorks - um máximo de 32000 dispositivos.

• X-10 - apenas é possível atribuir 256 endereços diferentes a dispositivos.

TDI - Transdutores domóticos inteligentes

Relatório Final 48/276

Alimentação de dispositivos:

• EIB - os dispositivos são alimentados directamente a partir do próprio meio de comunicação (normalmente, par entrelaçado ou os 220V). Apesar de tudo o meio para o envio de dados não é o mesmo que o meio que alimenta os dispositivos. A informação é modulada e conduzida sobre 24VDC.

• LonWorks - os dispositivos são alimentados a partir de fontes de alimentação próprias existentes em cada nó. Logo, o meio por onde são enviados os dados não é o mesmo que os alimenta.

• X-10 - os dispositivos são alimentados directamente da rede eléctrica, onde estão ligados, e também é a partir dela que enviam os dados.

Interacção com outros sistemas:

• EIB - pode interagir com outros sistemas através do uso de unidades conversoras – gateways, para além de ser possível comunicação em diferentes meios no mesmo sistema.

• LonWorks - apenas permite a utilização de diferentes meios de comunicação no mesmo sistema.

• X-10 - é sempre possível interagir com outros sistemas, embora seja bastante complexo de o fazer.

Arquitectura de sistema:

• EIB - normalmente este sistema opta por uma arquitectura descentralizada permitindo maior interacção entre os dispositivos, evitando uma organização hierárquica estruturada e elementos de supervisão de rede. Embora seja a situação mais usual este sistema pode também optar pela forma centralizada.

• LonWorks - inicialmente esta topologia de rede foi criada com o objectivo gestão centralizada a nível industrial. Mais tarde, devido a este tipo de gestão ser bastante complexa e de dificultar a possibilidade de o sistema se tornar aberto, surgiu assim a necessidade de tornar este sistema, o mais distribuído possível.

• X-10 - normalmente é utilizado uma arquitectura descentralizada.

Dispersão geográfica da sua influência:

X-10 tem maior impacto nos EUA enquanto o EIB tem maior divulgação na Europa (principalmente na União Europeia). O sistema LonWorks, na Europa, tem uma quota de mercado reduzida.

TDI - Transdutores domóticos inteligentes

Relatório Final 49/276

1.6 - O PROTOCOLO X-10

1.6.1 - ASPECTOS TEÓRICOS

Nesta secção explica-se o funcionamento do protocolo de comunicação X-10, utilizando a rede eléctrica, como meio de comunicação.

O método utilizado por este protocolo (X-10) é baseado num simples código de informação de 8 bits (1 byte) precedido por de um start code.

Este sistema utiliza bursts de 120kHz transmitidos sobre os 50Hz da rede eléctrica para representar a informação digital. Estes bursts representam um 0 ou um 1 dependendo da sua ausência ou presença imediatamente a seguir à passagem por zero do sinal da rede eléctrica.

A parte mais complicada desta tecnologia não é o protocolo em si, mas o método no qual é baseada a transmissão de dados de um dispositivo (transmissor) para um outro (receptor). A solução chave para a resolução deste cenário é que todos os dispositivos tenham um circuito integrado que detecte a passagem do sinal por zero, dada a necessidade de estarem sincronizados entre eles (figura 30).

Fig. 30 – Passagens por zero da rede eléctrica

O receptor está aberto para receber informação num espaço de tempo que dura desde a passagem do sinal por zero até 6ms depois. Fazem isto duas vezes por cada período do seno, ou seja, 100 vezes por segundo.

Fig. 31 – Diagrama temporal simplificado da recepção

TDI - Transdutores domóticos inteligentes

Relatório Final 50/276

Visto que entre o receptor e o emissor não há nenhum fio que os ligue directamente um ao outro existe necessidade de recorrer a um método que permita que a troca de dados seja feita através da rede eléctrica. A actual transmissão de dados binários é efectuada pelo envio de bursts de 1ms de duração e com frequência de 120kHz. Também é necessário o uso de pares de bits complementares. Assim, o 1 binário é identificado quando detectado um burst, imediatamente seguido por uma ausência de outro impulso no próximo zero crossing. O 0 binário é identificado quando é detectada uma ausência de impulso imediatamente seguida por uma presença de um impulso (Fig. 32).

Fig. 32 – Exemplo da transmissão de dados utilizando

Quando um dispositivo transmissor envia um comando, os dispositivos receptores necessitam saber para quem vai ser enviado. Para isso, os dispositivos identificam um ponto de partida bem definido (start point) e conhecido por todos os dispositivos X-10, que os informe que imediatamente a seguir a este ponto de partida se vai seguir um conjunto de bits de dados que vai conter toda a informação necessária. O start point é composto por, pelo menos, 6 ausências de impulsos, ou seja, 6 zeros lógicos seguidos por um código de início (start code) composto por 3 impulsos seguidos e uma ausência de impulso (1110) – ver figura 33.

Fig. 33 – Exemplo de um Start Code

TDI - Transdutores domóticos inteligentes

Relatório Final 51/276

Imediatamente a seguir ao start code seguem-se 4 bits de informação. Estes 4 bits representam o letter code, que compõem a primeira metade do endereço de destino (House code). Para tornar mais fácil a operação com os dispositivos por parte dos consumidores, estes primeiros 4 bits representam um código ao qual será atribuído uma letra. Existe, para tal, uma tabela que atribui a cada letra um código binário (figura 34).

Fig. 34 – Exemplo de um House Code

Imediatamente a seguir é enviado a segunda metade do endereço, chamado number code (figura 35). O último bit aparece como fazendo parte deste number code, mas na realidade é um bit de funcionalidade. Contudo, este bit de funcionalidade é um 0 lógico, para o caso de se querer representar o number code ou unit code. Caso esse bit seja um 1 lógico quer dizer que estamos na presença, não de um código de número, mas sim, de um código de comando! Por esta razão este código muitas vezes é chamado de function code, representando ou o number code ou o command code.

Fig. 35 – Exemplo de um number code

TDI - Transdutores domóticos inteligentes

Relatório Final 52/276

Com objectivo de obter maior confiança, redundância e para permitir melhor desempenho a repetidores de linha, o protocolo X-10 envia o “frame” em duplicado (figura 36).

Fig. 36 – Exemplo da transmissão em duplicado da trama

Depois de receber e interpretar os dados de endereço, os receptores ficam preparados para receber os dados de comando.

Nesta fase todos os módulos já sabem qual vai ser o responsável por receber os dados de comando. Estes dados vão indicar aos respectivos módulos receptores quais vão ser as acções que têm de realizar. Como já foi referido anteriormente, todos os frames de dados têm de começar por um “start code”. Depois do start code (1110) segue-se, o letter code (igual ao que já foi enviado anteriormente, nos dados de endereço). De imediato temos por fim o código de comando (comand code), que impõem que o último bit do código de funcionalidade seja um 1 lógico, indicando que estamos na presença de um comando.

A figura 41 só referência os seis comandos mais usados actualmente. Mais à frente mostraremos um diagrama com todos os comandos existentes

Fig. 37 – Exemplo de um command code

TDI - Transdutores domóticos inteligentes

Relatório Final 53/276

A figura seguinte mostra um exemplo da transmissão de dois frames de dados. Esta transmissão gasta 47 ciclos da onda de 50Hz. O quer dizer que demora 0,94 segundos a ser recebida pelo módulo receptor. Juntando a este tempo o tempo que os módulos podem demorar a interpretar e executar o comando podemos dizer que, normalmente é preciso 1 segundo para enviar, receber e executar um comando. Contudo, há comandos que não precisam de tanto tempo para serem enviados.

Podemos dar como exemplo o envio do comando “All lights on”. Este comando não necessita enviar o frame de endereço (visto que a ordem é para todos os receptores), bastando enviar apenas o frame de comando. Isto faz com que o número de ciclos gastos seja reduzido provocando também uma diminuição no tempo de transmissão do comando.

Fig. 38 – Envio de uma trama completa

Até agora, todas as figuras mostram a presença de apenas uma fase da nossa rede eléctrica, o que não está de todo correcto.

Na realidade o sistema X-10 tem de lidar com as 3 diferentes fases da nossa rede eléctrica. Assim, todos os transmissores X-10 devem enviar, não apenas 1 mas sim 3 impulsos para a rede (figura 39).

Fig. 39 – Envio de burts para o sistema trifásico

TDI - Transdutores domóticos inteligentes

Relatório Final 54/276

Código estendido

Para que o protocolo X-10 não se tornasse limitado criou-se uma extensão ao protocolo já existente tornando-o capaz de comunicar com outros dispositivos de forma mais eficaz e complexa.

Relembrando a tabela de comando verifica-se a existência de 3 tipos de códigos estendidos Ext Code 1, 2 e 3.

Fig. 40 – Tabela de comandos

Só o Ext Code 1 tem um formato de mensagem conhecido e definido com um comprimento de 31 ciclos (62 bits).

O formato da trama é a descrita na figura em baixo.

Fig. 41 – Formato da trama estendida

O campo “Command” está dividido em dois sub-campos.

• Type (4 bits) – Toma valores entre 0 e 15 mas de acordo com o protocolo X-10 estão apenas definidos 6 tipos.

• Funct (4 bits) – Ordena vários comandos de acordo com o tipo definido.

TDI - Transdutores domóticos inteligentes

Relatório Final 55/276

1.6.2 - ASPECTOS PRÁTICOS

Além do protocolo X-10 em si há que ter em atenção a vários pormenores como os diagramas temporais, tempo de espera entre comandos e a possibilidade e evitar colisões no envio de tramas estendidas.

Assim os burts deverão ter a duração de 1ms e deverão estar espaçados entre eles aproximadamente 2,3ms.

O primeiro burst é enviado imediatamente a seguir ao “zero crossing” de uma das três fases do sinal da rede; o segundo é enviado 3.3ms depois desse “zero crossing”, ou seja, a 2.3ms do fim do primeiro; o terceiro é enviado 6.7ms depois do referido “zero-crossing”, ou seja, a 2.3ms do fim do segundo (5.7ms do fim do primeiro).

Fig. 42 – Tempo entre bursts

Contudo, se os impulsos forem enviados depois de ultrapassados 200µs do “zero-crossing” os receptores podem não detectar os dados correctamente.

Fig. 43 – Tempo máximo aconselhado para o envio do primeiro burst

O módulo para enviar dados deverá esperar pelo menos 8, 9 ou 10 meios ciclos de onda para poder efectuar a transmissão. Se um bit for detectado nesse tempo, o dispositivo

TDI - Transdutores domóticos inteligentes

Relatório Final 56/276

transmissor deverá reiniciar o tempo de espera e voltar a contar os 8, 9 ou 10 meios ciclos.

O sistema de código estendido faz com que a quantidade de informação das mensagens que são trocadas seja maior, o que requer que os transmissores evitem colisões de mensagens sempre que possível. Assim, quando uma colisão ocorre pode ser detectada e resolvida.

Depois de detectar que a linha está livre, (espera com sucesso dos 8, 9 ou 10 ciclos) o transmissor deve escutar a rede sempre que “envia um zero” (ausência de burst). Se ocorrer uma colisão o transmissor deve abortar imediatamente a sua transmissão e voltar a fase inicial de acesso à linha.

TDI - Transdutores domóticos inteligentes

Relatório Final 57/276

2 - OBJECTIVOS E REQUISITOS

Este projecto surgiu com o objectivo inicial de serem estudados, criados e implementados sensores aplicáveis na área da domótica. Estes sensores, para além de se poderem auto-instalar, seriam também capazes de comunicar com qualquer um dos três sistemas domóticos mais importantes (X-10, LonWorks e KNX). Devido a uma grande incompatibilidade e diferenças de arquitectura, entre os sistemas em estudo, não nos foi possível seguir os objectivos inicialmente propostos.

Assim os objectivos foram reformulados para:

• O estudo dos aspectos funcionais de cada um sistemas;

• O desenvolvimento de módulos utilizando a tecnologia X-10. Os módulos devem ser independentes do tipo de sensor ou actuador a que se destinam, possuir agendamento e capacidade de auto-instalação.

TDI - Transdutores domóticos inteligentes

Relatório Final 58/276

3 – MÓDULOS DESENVOLVIDOS

3.1 INTRODUÇÃO

Foram desenvolvidos cinco módulos, cada um com funcionalidades distintas como a monitorização, sensorização e actuação:

• Módulo “Interface PC” – Este módulo interage com todos os outros módulos, permitindo controla-los e configura-los através de uma aplicação gráfica para PC utilizando a porta série (RS-232)

• Módulo “Central de Inundação” – Permite a monitorização de um, ou mais compartimentos, através de quatro sensores de inundação. Quando um dos sensores é activo, a central activa um dispositivo sonoro e envia um comando pré-configurado pela rede, actuando num outro módulo (p.e. módulo “actuador DC” ligado a uma electro-válvula). Os sensores podem ser inibidos por um determinado tempo colocando a central em stand-by.

• Módulo “Sensor” – Este módulo possui uma interface universal para um sensor de contacto do tipo ON/OFF. Quando ocorre uma mudança de estado no sensor é enviado um comando pela rede à semelhança da central de inundação.

• Módulo “Actuador AC” – Controla cargas do tipo AC de acordo com o comando recebido pela rede. Possui um relógio permitindo o controlo da carga num determinado momento pontual ou periodicamente. Em qualquer altura é também possível actuar sobre a carga com o auxílio de dois botões.

• Módulo “Actuador DC” – Este módulo é em tudo semelhante ao módulo “Actuador AC” mas este controla cargas DC.

Todos estes módulos à excepção do módulo “Interface PC” reagem aos comandos standard STATUS e HAIL descritos no protocolo X-10[16] e também ao conjunto de comandos estendidos do tipo 7 criado por nós (descrito na secção 3.4).

3.2 DESCRIÇÃO FUNCIONAL

O diagrama de blocos da figura 44 representa na generalidade todos os módulos desenvolvidos neste projecto e estão divididos em três grupos:

• X-10 – Efectua o acoplamento com a rede eléctrica permitindo a transmissão e a recepção dos sinais de acordo com o protocolo X-10[16]. Dentro deste grupo está também incluído um circuito que detecta as passagens por zero (quando a onda sinusoidal tem uma amplitude de 0V) da rede eléctrica;

• MCU – Efectua todo o processamento e controlo do módulo utilizando o microcontrolador PIC16F877A com o auxílio de um real-time clock (DS12C877).

TDI - Transdutores domóticos inteligentes

Relatório Final 59/276

Os módulos estão também dotados de uma interface série (RS232) para a comunicação com o PC;

• Alimentação – Fornece alimentação ao circuito utilizando uma solução com transformador disponibilizando uma tensão de 5 e 26V.

REDE

PC

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

RS-232

RTC

Dispositivo externo

X-10MCU

ALIMENTAÇÃO

Fig. 44 - Diagrama de blocos geral dos módulos desenvolvidos

Nota 1: Só o módulo “interface PC” inclui na PCB a interface RS-232. Todos os outros módulos têm apenas um conector do tipo RJ-12 que pode ser ligado externamente a uma interface visto que em funcionamento normal os restantes módulos não necessitam de comunicar com o PC.

Nota 2: O real-time clock está apenas implementado nos módulos actuadores (AC e DC) tornando o agendamento do tipo local o que é mais fiável.

TDI - Transdutores domóticos inteligentes

Relatório Final 60/276

3.3 HARDWARE COMUM A TODOS OS MÓDULOS

3.3.1 ALIMENTAÇÃO

A alimentação dos módulos é feita recorrendo a um transformador 220V/18V de dois enrolamentos secundários de 0.75VA.

Fig. 45 - Alimentação dos módulos

Obtém-se duas tensões de 5V e 26V, recorrendo, no caso da primeira, a uma rectificação de meia onda seguido de uma regulação. Para a tensão de 26V efectua-se uma rectificação de onda completa.

De notar que quando o módulo transmite sinais X-10 para a rede, o circuito consome mais corrente (por volta de 300mA) do que aquela que o transformador pode fornecer. Como a transmissão não ocorre sistematicamente utilizou-se um condensador com uma capacidade relativamente elevada para que este suporte essa corrente. O dimensionamento segue a lei:

uFuFCms

CmAdtdvCI 22002000

203300 ≅=⇔=⇔=

De notar que o período da onda sinusoidal da rede eléctrica é de 20 ms.

3.3.2 ACOPLAMENTO

O acoplamento é uma interface entre a rede eléctrica e os circuitos de baixa tensão: circuito de transmissão e o circuito de recepção.

Durante o desenvolvimento dos módulos foram testados dois tipos de acoplamento:

• Recorrendo um conjunto de filtros LC;

• Usando um transformador de altas-frequências.

TDI - Transdutores domóticos inteligentes

Relatório Final 61/276

Fig. 46 - Acoplamento com a rede eléctrica

O conjunto de filtros LC (figura 47) não é mais que um filtro LC passa-banda duplo. Para sintonizar este filtro para os 120 KHz podemos recorrer a fórmula:

( ) 23211 21

21

LCCLCFc

+==

ππ

Se L1 = 47uH então,

nFnFCC

3342.3710472

110120 161

3 ≅=⇔××

=×−π

E igualmente se L2 = 47uH temos,

( )nFCC

CC42.37

10472

110120 32632

3 =+⇔××+

=×−π

Se nFC 332 = então nFnFC 7.442.43 ≈=

A resistência R1 limita o mínimo da impedância de entrada do filtro.

Fig. 47 - Acoplamento utilizando um conjunto de filtro LC

TDI - Transdutores domóticos inteligentes

Relatório Final 62/276

Tendo em atenção os custos ter-se-ia optado pelo conjunto de filtros LC, mas esta solução tem uma grande desvantagem: não permite o isolamento da rede eléctrica. Assim optou-se pelo transformador HF (High Frequency) que além de disponibilizar o isolamento da rede eléctrica também realiza a filtragem apropriada sem o recurso a filtros externos.

Recorreu-se ao transformador P2821[30] da ETAL[29] que opera numa gama de frequências entre 95 a 125 KHz tendo uma razão de transformação, n, de 1:3.22 e reactância de fugas de aproximadamente 600uH. Para funcionar correctamente o transformador é sintonizado para a frequência da portadora com o auxílio de condensadores.

Fig. 48 - Acoplamento utilizando um transformador HF

A resistência R1 foi colocada como protecção devido a picos de corrente.

3.3.3 DETECÇÃO DO ZERO DA REDE

A detecção do zero da rede é obtida operação por um abaixamento da amplitude da onda sinusoidal da rede eléctrica.

Para isso utilizou-se uma resistência (R16) ligada directamente à rede e limitou-se a tensão colocando um díodo para que as arcadas negativas não excedessem os 0.7V. Por fim utilizou-se um opto-acoplador (6N136) para efectuar o isolamento entre o módulo e a rede.

Fig. 49 - Detecção da passagem por zero da rede

Devido ao atraso do opto-acoplador o sinal obtido à saída não tem um duty-cycle exacto de 50% mas sim um valor muito próximo deste como se pode observar na figura 50.

TDI - Transdutores domóticos inteligentes

Relatório Final 63/276

Fig. 50 - Sinal à saída do opto-acoplador

Como esta discrepância é pequena e não ultrapassa os tempos máximos impostos pelo protocolo X-10 (descritos no ponto 1.5.3), o funcionamento correcto dos módulos não é afectado.

3.3.4 RECEPÇÃO

Para a recepção dos sinais X-10 foi efectuado um detector de envolvente “sintonizado” para frequência de 120 KHz. O diagrama de blocos seguinte, fig. 51, ilustra o exposto:

Fig. 51 - Diagrama de blocos do circuito da recepção

TDI - Transdutores domóticos inteligentes

Relatório Final 64/276

Apesar do transformador HF efectuar já uma filtragem passa-banda optou-se por incluir também um filtro passa-alto simples para eliminar eventual ruído.

Fig. 52 - Esquema eléctrico da recepção

Dimensionou-se o filtro para uma frequência de corte inferior aos 120 KHz, com a expressão:

KHzRC

f db 510822.410110332

12

1 3933 ≅×=

××××==

−ππ

Assegura-se assim que o sinal pretendido passa completamente para a etapa amplificadora. O sinal é em seguida amplificado utilizando uma série de inversores, configurados como amplificadores de alto ganho, sintonizados para os 120KHz. Na etapa seguinte é efectuada uma amplificação simples e, por fim, é feita a detecção de envolvente. Este último detector é formado com um díodo, um condensador e uma resistência. A saída é ligada a um “buffer”, utilizando um inversor, e este, por fim, liga ao microcontrolador.

O microcontrolador apenas tem que verificar se dentro do instante de transmissão de dados, existe ou não portadora.

TDI - Transdutores domóticos inteligentes

Relatório Final 65/276

Fig. 53 - Sinal à saída do bloco de recepção

3.3.5 TRANSMISSÃO

A transmissão é feita enviando uma portadora de 120 KHz (+/- 2KHz) para a rede eléctrica. O PWM do PIC16F887A gera essa frequência. Assim só é necessário amplificar este sinal de modo que seja acoplado correctamente na rede. A figura 54 ilustra a etapa amplificadora desenvolvida.

Fig. 54 - Esquema eléctrico da recepção

Na realidade o sinal transmitido não se mantém nos 26V como seria de esperar teoricamente. Este aspecto foi já referido no ponto 3.3.1, onde foi dimensionado o condensador, de 2200uF, para que a ondulação seja de aproximadamente 3V.

TDI - Transdutores domóticos inteligentes

Relatório Final 66/276

Fig. 55 - Sinal à saída do bloco de transmissão

3.3.6 INTERFACE RS232

A interface RS232 é conseguida com a ligação do microcontrolador ao PC com um DS275 (equivalente ao MAX232). O circuito eléctrico está representado na figura 56.

Fig. 56 - Esquema eléctrico da interface RS232

Os sinais do PC, apesar de fornecerem pouca corrente, foram suficientes para alimentar o DS275 e os opto-acopladores.

TDI - Transdutores domóticos inteligentes

Relatório Final 67/276

Como foi já referido criou-se um módulo RS-232 em separado para a comunicação dos módulos de actuação e sensorização, pois não necessitam de estar permanentemente em contacto com o PC sendo apenas necessário para efeitos de actualização de firmware.

Fig. 57 - Fotografia do módulo RS232

3.4 SOFTWARE COMUM A TODOS OS MÓDULOS

O software comum a todos os módulos incide principalmente sobre a implementação da comunicação X-10.

Utilizaram-se várias funcionalidades do PIC16F877A para o seu desenvolvimento.

PWM (Pulse Width Modulator)

A PWM que gera a portadora de 120 KHz necessária para a transmissão dos dados para a rede.

Para que a PWM opere à frequência correcta é necessário configura-la. Como esta utiliza o temporizador TIMER2, foi necessário calcular os valores correctos para que este entre em overflow com no período correcto. Recorrendo a algumas funções built-in do compilador de C[49] configurou-se o temporizador da forma a seguir descrita.

Utilizou-se a formula em baixo indicada para determinar os parâmetros da função setup_timer_2(mode, period, postscale);

( ) postscaleperiodeF

f

OSC

PWM

×+×××=

1mod411

TDI - Transdutores domóticos inteligentes

Relatório Final 68/276

( ) 11344680.7

11120

×+×××=

MHz

KHz

• mode é um divisor de frequência podendo tomar os valores de 1, 4, ou 16;

• period não é mais que um contador deste temporizador carregado com o valor selecionado, que vai sendo decrementado até ocorrer overflow (255 – period);

• postscale determina quantas vezes o contador entra em overflow antes de gerar a interrupção.

A função que configura a PWM tem apenas um parâmetro que determina o duty-cycle da onda quadrada set_pwm1_duty(value);.

Este parâmetro pode ser calculado recorrendo à seguinte formula:

4mod1×××= e

FvalueT

OSChigh

Como queremos um duty-cycle de 50%, o tempo que a arcada positiva se mantém activa terá que ser metade do período.

4468.7

12

1201

×××=MHz

valueKHz

2=value

Para controlar a PWM recorre-se à função setup_ccp1(mode); que activa (mode toma o valor de CCP_PWM) ou inibe a PWM (mode toma o valor de CCP_OFF).

Utilizou-se também o TIMER0 para várias funções não sobrepostas:

• Controlar a duração da PWM;

• Temporizador para o envio da portadora nas três fases;

• Temporizador para a recepção.

Assim configurou-se o TIMER0 com um divisor de 64 para que fosse possível obter intervalos na ordem dos milissegundos.

Setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL);

TDI - Transdutores domóticos inteligentes

Relatório Final 69/276

Dependo da função desejada carregou-se o timer com o valor desejado.

No caso da duração da PWM o valor deveria ser de aproximadamente 1ms, mas comparada com os módulos comerciais este valor foi reduzido para 0,7ms. Assim

utilizando a fórmula valueF

TOSC

×××= 6441 obteve-se o valor pretendido para a

função set_timer0(value);.

)1(64468.7

17.0 +×××= valueMHz

ms

20=value

Interrupção externa

A interrupção externa (INT0) foi utilizada para a detecção dos zeros da rede.

A comunicação do módulo com a rede é prioritária e fulcral, assim é dentro da interrupção que foi desenvolvido a maior parte do código. Pois desta maneira microcontrolador não atende outras interrupções indesejadas. Temos é que ter a certeza que o programa incluído na interrupção se completa antes de ocorrer a próxima.

As figuras seguintes mostram os dois fluxogramas: do programa principal e da interrupção, respectivamente.

TDI - Transdutores domóticos inteligentes

Relatório Final 70/276

N

N

S

S

Configura RS232, portas lógicas, PWM e

timers

Inicia variáveis

Ciclo Infinito

Recebeu comando?

A transmitir dados?

Acções específicas para cada módulo

Acções específicas para cada módulo

Início

Fig. 58 – Fluxograma do programa principal

TDI - Transdutores domóticos inteligentes

Relatório Final 71/276

Fig. 59 – Fluxograma da interrupção

TDI - Transdutores domóticos inteligentes

Relatório Final 72/276

Facilmente se observa no fluxograma da figura 58, que é no programa principal que se efectuam todas as operações não prioritárias; no caso do módulo “Interface PC” é tratada a comunicação com a aplicação gráfica. Nos restantes módulos é efectuada a monitorização e gestão dos sensores/actuadores, o agendamento e funções internas dos módulos.

De notar que os timers da figura 59 têm atrasos com valores inferiores ao que está descrito no protocolo mas, há que ter em conta o tempo que é gasto a correr o código.

Configuração e agendamento

Valor (hex) Descrição Variáveis a verificar 0x01 Todas as horas Min 0x02 Todos os dias Hora, Min 0x03 Todas as semanas Hora, Min, DiaDaSem 0X04 Todos os meses Hora, Min, DiaDoMes 0x05 Todos os anos Hora, Min, DiaDoMes, Mes 0x06 Uma vez Hora, Min, DiaDoMes, Mes, Ano 0xFF Nunca

Quadro 7. Descrição das opções de agendamento

Endereço (hex) Tamanho (bits) Descrição 0x00 16 Número de série 0x02 8 House Code 0x03 8 Unit Code 0x04 8 Opção de agendamento 0x05 8 Hora 0x06 8 Minuto 0x07 Dia do mês 0x08 Dia da semana 0x09 Mês 0x10 Ano 0x11 Comando … … … 0xF4 8 Opção de agendamento 0xF5 8 Hora 0xF6 8 Minuto 0xF7 8 Dia do mês 0xF8 8 Dia da Semana 0xF9 8 Mês 0xFA 8 Ano 0xFB 8 Comando

Quadro 8. Estrutura da EEPROM

TDI - Transdutores domóticos inteligentes

Relatório Final 73/276

Na configuração foi adicionado um número de série de 16 bits aos módulos que é guardado na EEPROM, permitindo configurar o House Code e Unit Code remotamente.

Para o agendamento foi criado uma lista de possíveis opções num máximo de 31 agendamentos distintos.

Este limite de 31 agendamentos é devido à EEPROM do microcontrolador que tem apenas uma memória de 256 bytes.

Assim a estrutura da EEPROM toma a forma da tabela do quadro 8 .

Para implementar estas novas funcionalidades disponíveis em todos os módulos exceptuando o módulo “Interface PC” foi criado um novo tipo de dados (Type 6) no comando extended message 1[16] para efectuar a configuração e agendamento.

Assim criou-se o seguinte tipo de dados estendidos:

DATA A7 A6 A5 A4 A3 A2 A1 A0

TYPE CMD Descrição

Configuração House Code Unit Code 6 1 Envia os bits menos significativos do

número de série House Code Unit Code 6 2 Envia os bits mais significativos do

número de série House Code Unit Code 6 3 Altera House Code e Unit Code 0 0 0 0 C C C C 6 4 Comando a enviar quando sensor

activo Agendamento Opção Comando 6 5 Envia Opção de agendamento e o

respectivo comando 0 0 0 0 0 0 0 0 6 6 Envia relógio H H H H H H H H 6 7 Envia hora M M M M M M M M 6 8 Envia minuto S S S S S S S S 6 9 Envia segundo DM

DM

DM

DM

DM

DM

DM

DM

6 10 Envia mês

M M M M DS DS DS DS 6 11 Envia ano A A A A A A A A 6 12 Envia dia do mês C C C C C C C C 6 13 Envia dia da semanaa 15 Envia Termino (END) X x x x x x x x 0 Confirma

Quadro 9. Descrição dos dados estendidos do tipo 6

TDI - Transdutores domóticos inteligentes

Relatório Final 74/276

3.5 - MÓDULO 1: MÓDULO “INTERFACE PC”

3.5.1 - DESCRIÇÃO DO HARDWARE

O módulo “interface PC” não tem hardware específico, pois não controla nenhum dispositivo externo. A sua função é apenas comunicar com a aplicação gráfica através da porta RS-232.

REDE

PC

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

RS-232

X-10MCU

ALIMENTAÇÃO

Fig. 60 - Diagrama de blocos do módulo “Interface PC”

Todos os circuitos existentes neste módulo estão descritos na secção 3.3 deste relatório.

A figura 61 é uma fotografia do módulo. De notar as correcções efectuadas na PCB pois a qualidade de fabrico existente não é de todo adequada à complexidade deste tipo de placas.

TDI - Transdutores domóticos inteligentes

Relatório Final 75/276

Fig. 61 - Fotografia do módulo “Interface PC”

3.5.2 - DESCRIÇÃO DO SOFTWARE

Além do software já descrito na secção 3.4 exceptuando a configuração e agendamento foi implementado um protocolo de comunicação com a porta série.

As tramas têm o seguinte formato:

Fig. 62 – Formato da trama

Onde C0 e Cn indicam o inicio e fim de trama utilizando o carácter ASCII 22 e 23 respectivamente.

O carácter C1 se 01, indica que é feita uma comunicação interna entre a aplicação e o módulo ou vice-versa. Se 02 indica que se trata de um código X-10.

Caso C1 seja 02, C2 indica quando se trata de um código standard ou estendido.

TDI - Transdutores domóticos inteligentes

Relatório Final 76/276

Fig. 63 – Formato da trama para comandos standard

Fig. 64 – Formato da trama para comandos estendidos

Sempre que é enviado um comando pelo módulo é enviada uma confirmação para a aplicação gráfica do tipo descrito em baixo:

Fig. 65 – Confirmação do envio do comando

Este protocolo tanto se aplica para a transmissão como para a recepção do módulo ou da aplicação e está implementado na parte do programa principal.

TDI - Transdutores domóticos inteligentes

Relatório Final 77/276

Início

Envia comando recebido da rede por

RS-232N

N

S

S

Configura RS232, portas lógicas, PWM e

timers

Inicia variáveis

Ciclo Infinito

Recebeu comando?

A transmitir dados?

Processa dados e efectua acção

Recebeu dados por RS-

232?

S

N

Fig. 66 – Fluxograma do programa principal

O bloco “Processa dados e efectua acção” descrito no fluxograma indica todo o programa que constrói a trama e responde à aplicação gráfica ou activa a ordem para o envio de dados X-10 pela rede eléctrica.

TDI - Transdutores domóticos inteligentes

Relatório Final 78/276

3.6 - MÓDULO 2: MÓDULO “CENTRAL DE INUNDAÇÃO”

3.6.1 - DESCRIÇÃO DO HARDWARE

O módulo “Central de inundação” além do hardware comum possui também quatro sensores de inundação, um botão de inibição e uma sirene (buzzer) que indica a activação de um dos sensores.

REDE

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

BUZZER

X-10MCU

ALIMENTAÇÃO

4 sensores de inundação

BOTÃO

DE

INIBIÇÃO

Fig. 67 - Diagrama de blocos do módulo “Central de inundação”

Os circuitos existentes neste módulo da parte da comunicação X-10 estão descritos na secção 3.3 deste relatório.

Os sensores de inundação baseiam-se num conjunto de eléctrodos que funcionam como interruptor. A Fig. 68 mostra o circuito de detecção implementado.

TDI - Transdutores domóticos inteligentes

Relatório Final 79/276

Fig. 68 – Circuito de um dos sensores de inundação

A saída deste sensor obtemos um sinal do tipo 0V/5V que indica a presença ou não de líquido junto do sensor.

Os esquemas para os circuitos do buzzer e do botão de inibição estão ilustrados nas figuras seguintes:

Fig. 69 – Circuito para o buzzer

Fig. 70 – Circuito para o botão de pressão

TDI - Transdutores domóticos inteligentes

Relatório Final 80/276

A ligação para os eléctrodos é feita de forma cablada utilizando fichas RJ-11 nas duas extremidades.

Fig. 71 - Fotografias dos eléctrodos

A fotografia da Fig. 72 ilustra a PCB do módulo “Central de inundação”. De notar a ficha RJ-12 do lado esquerdo, que liga o módulo RS-232 já descrito na secção 3.3.6 para upgrade de firmware.

Fig. 72 - Fotografia do módulo “Central de inundação”

TDI - Transdutores domóticos inteligentes

Relatório Final 81/276

3.6.2 - DESCRIÇÃO DO SOFTWARE

O software deste módulo é comum ao descrito na secção 3.4 à excepção do agendamento.

Foi necessário desenvolver uma interface para controlar as entradas (sensores e botão de pressão) e as saídas (LEDs e buzzer).

A Fig. 73 mostra o fluxograma, simplificado, do programa principal, onde foi implementado este interface.

Fig. 73 – Fluxograma do programa principal

TDI - Transdutores domóticos inteligentes

Relatório Final 82/276

3.7 - MÓDULO 3: MÓDULO “SENSOR”

3.7.1 DESCRIÇÃO DO HARDWARE

O módulo “Sensor” além do hardware comum possui uma interface para um sensor de contacto do tipo ON/OFF.

REDE

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

X-10MCU

ALIMENTAÇÃO

Sensor universal

Fig. 74 - Diagrama de blocos do módulo “Sensor”

Os circuitos existentes neste módulo da parte da comunicação X-10 estão descritos na secção 3.3 deste relatório.

Como a interface para o sensor é do tipo ON/OFF à saída do circuito teremos um sinal que assume dois estados 5V e 0V.

O módulo está isolado em relação ao sensor por razões de segurança, mas torna-se assim obrigatório alimentar o sensor com auxílio a uma fonte externa.

TDI - Transdutores domóticos inteligentes

Relatório Final 83/276

Fig. 75 – Circuito da interface para o sensor

Para testes foi utilizado um sensor de movimento (PIR) da IntelliSense[43] que efectua a mudança de estado através de um relé.

Fig. 76 - Fotografia do PIR (Sensor de Movimento)

A fotografia da PCB do módulo “Sensor” pode ser vista na Fig. 77. Como já foi referido no módulo “Central de Inundação”, a ficha RJ-12 liga o módulo RS-232 para upgrade de firmware.

TDI - Transdutores domóticos inteligentes

Relatório Final 84/276

Fig. 77 - Fotografia do módulo “Sensor”

3.7.2 - DESCRIÇÃO DO SOFTWARE

O software deste módulo é comum ao descrito na secção 3.4 à excepção do agendamento.

À semelhança do módulo “Central de Inundação” foi necessário desenvolver uma interface para controlar a entrada do sensor.

O fluxograma, simplificado, do programa principal, onde foi implementado esta interface, pode ser visto na Fig. 78

TDI - Transdutores domóticos inteligentes

Relatório Final 85/276

Início

N

N

S

S

Configura RS232, portas lógicas, PWM e

timers

Inicia variáveis

Ciclo Infinito

Recebeu comando?

A transmitir dados?

Verifica estado do sensor

Comando para este módulo?

Processa e efectua acção pré-

definida

Mudança de estado?

Efectua acção pré-definida

S

N

S

N

Fig. 78 – Fluxograma do programa principal

TDI - Transdutores domóticos inteligentes

Relatório Final 86/276

3.8 - MÓDULO 4: MÓDULO “ACTUADOR AC”

3.8.1 - DESCRIÇÃO DO HARDWARE

O módulo “Actuador AC” além do hardware comum (bloco de comunicação X-10 e a alimentação) possui uma interface para controlar uma carga AC, dois botões de pressão que permitem o controlo local dessa mesma carga e um real-time clock para efectuar o agendamento local.

REDE

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

RTC

Carga AC

X-10MCU

ALIMENTAÇÃO

2

BOTÕES

DE

PRESSÃO

Fig. 79 - Diagrama de blocos do módulo “Actuador AC”

Os circuitos existentes neste módulo da parte da comunicação X-10 estão descritos na secção 3.3 deste relatório.

TDI - Transdutores domóticos inteligentes

Relatório Final 87/276

Para a interface de controlo de cargas AC, recorreu-se a um triac aqui funcionando como interruptor.

O opto-triac (MOC3021) é responsável por detectar os 5V provenientes do microcontrolador fornecendo corrente à base do BT139 e este último activa a carga.

O módulo está isolado em relação ao resto do circuito actuador por razões de segurança. Foi também adicionado um conjunto de resistências e condensadores (R23, R24, C26 e C27) evitando que, pequenos picos de corrente, danifiquem o BT139 e o MOC3021.

Fig. 80 – Circuito da interface para controlar cargas AC

Este módulo permite agendamento e assim é necessário recorrer a um real-time clock. Poderia ter-se utilizado como relógio as detecções de zero, já que ocorrem 50 vezes por segundo, mas assim teria que se implementar todo o interface para um relógio e quando a alimentação os dados perdiam-se.

Assim utilizou-se o DS12C877[38] que além de existir inúmera documentação sobre ele tem também uma pilha que permite guardar as suas definições por muito tempo.

A fotografia da PCB do módulo “Actuador AC” está ilustrada na Fig. 81.

TDI - Transdutores domóticos inteligentes

Relatório Final 88/276

Fig. 81 - Fotografia do módulo “Actuador AC”

3.8.2 - DESCRIÇÃO DO SOFTWARE

O software deste módulo é comum ao descrito na secção 3.4.

Foram desenvolvidos drivers para o real-time clock, tornando assim a sua utilização mais simplificada.

O RTC é verificado de 500ms em 500ms recorrendo à detecção de zero evitando-se assim libertar processamento ao microcontrolador.

RTCCount++;

if (RTCCount > 25) {

RTCCount = 0;

RTCUpdate = 1;

}

À excepção do extracto de código anterior todo o desenvolvimento foi efectuado no programa principal.

Sempre que ocorre uma alteração no relógio (resolução a nível do minuto) verifica se há agendamentos a efectuar.

TDI - Transdutores domóticos inteligentes

Relatório Final 89/276

Na parte de gestão do agendamento desenvolveram-se também diversas rotinas para interagir com a EEPROM.

O fluxograma, simplificado, do programa principal, é o seguinte:

Início

N

N

S

S

Configura RS232, portas lógicas, PWM e

timers

Inicia variáveis

Ciclo Infinito

Recebeu comando?

A transmitir dados?

Verifica estado dos botóes de pressão

Comando para este módulo?

Processa e efectua acção pré-

definida

Mudanças de estado?

Efectua acção pré-definida

S

N

S

N

Necessário update ao relógio?

Actualiza relógio e verifica agendamentos

Agendamento a efectuar?

Efectua acção pré-definida

S

S

N

N

Fig. 82 – Fluxograma do programa principal

TDI - Transdutores domóticos inteligentes

Relatório Final 90/276

3.9 - MÓDULO 5: MÓDULO “ACTUADOR DC”

3.9.1 - DESCRIÇÃO DO HARDWARE

O módulo “Actuador DC” é semelhante ao módulo “Actuador AC” com a excepção de este controlar cargas DC. A fig. 84 ilustra o seu esquema de princípio.

REDE

ZERO

ACOPLAMENTO

TX

RX

MICRO

CONTROLADOR

RTC

Carga DC

X-10MCU

ALIMENTAÇÃO

2

BOTÕES

DE

PRESSÃO

Fig. 83 - Diagrama de blocos do módulo “Actuador DC”

Para a interface de controlo de cargas DC, recorreu-se a um transístor funcionando como interruptor.

O opto-acoplador (4N25) é responsável por detectar os 5V provenientes do microcontrolador fornecendo corrente à base do BD139 e este último active a carga.

TDI - Transdutores domóticos inteligentes

Relatório Final 91/276

Quando a carga é desactivada, a corrente é descarregada para o díodo e para o zener. Efectua-se assim um escoamento controlado da corrente da carga, evitando descargas bruscas de corrente, que poderiam por em causa a segurança do actuador.

Fig. 84 – Circuito da interface para controlar cargas DC

Para testes foram utilizados dois actuadores: uma electro-válvula e uma sirene.

Fig. 85 – Fotografias da electro-válvula e da sirene

A figura seguinte mostra a fotografia da PCB do módulo “Actuador DC”. De notar que, à semelhança do módulo “Interface PC”, se teve que efectuar correcções de modo que o seu funcionamento fosse correcto.

TDI - Transdutores domóticos inteligentes

Relatório Final 92/276

Fig. 86 - Fotografia do módulo “Actuador DC”

3.9.2 - DESCRIÇÃO DO SOFTWARE

O software deste módulo é em tudo igual ao módulo “Actuador AC” já que a interface de controlo da carga é transparente para o microcontrolador. De notar apenas que o sinal de controlo está invertido em relação ao módulo “Actuador AC”.

Também o fluxograma é igual ao do módulo “Actuador AC”.

TDI - Transdutores domóticos inteligentes

Relatório Final 93/276

4 – APLICAÇÃO GRÁFICA “X-10 INTERFACE PARA PC”

Foi desenvolvida uma aplicação gráfica recorrendo ao Borland Delphi 7[48] tento como finalidade efectuar a gestão, controlo e configuração dos módulos desenvolvidos.

Com esta aplicação é assim possível:

• Controlar todos os módulos, tantos os aqui desenvolvidos como os comerciais através de comandos standard e estendidos;

• Configurar e efectuar o agendamento dos módulos desenvolvidos;

• Fazer a escuta da rede eléctrica criando um registo com todos os comandos que nela circularam.

Fig. 87 – Aplicação gráfica “X-10 Interface para PC”

É utilizado o módulo “Interface para PC” para efectuar a comunicação com a rede eléctrica utilizando a porta RS-232. O protocolo entre eles foi já descrito na secção 3.5.2.

Adicionou-se o componente ComPort 3.0[47] para facilitar a implementação da comunicação série.

TDI - Transdutores domóticos inteligentes

Relatório Final 94/276

Foi criada uma janela que permite escolher e guardar as definições da porta série evitando sempre que se abre a aplicação seja necessária configura-la.

Fig. 88 – Definições da porta série

Recorrendo a um sistema de arquivos é possível ter várias listas de módulos na mesma aplicação, permitindo assim, uma grande versatilidade caso se utilize a mesma aplicação em diversos locais geográficos.

Fig. 89 – Gestão dos arquivos que contêm a listagem dos módulos

Tanto as definições da porta série como do arquivo carregado por defeito são guardadas no registo do Windows.

TDI - Transdutores domóticos inteligentes

Relatório Final 95/276

A gestão local dos módulos é feita através do menu Modules. Em qualquer altura é possível adicionar, editar ou remover módulos.

Fig. 90 – Janela que permite a inserção de módulos

A gestão e controlo remoto dos módulos propriamente dita, é feita no menu principal e no menu Tools.

Fig. 91 – Comandos que permitem o controlo e gestão remota dos módulos

TDI - Transdutores domóticos inteligentes

Relatório Final 96/276

Fig. 92 – Menus de configuração remota dos módulos

Como já foi referido é também possível efectuar uma escuta da actividade X-10 da rede eléctrica.

Fig. 93 – Registo da actividade X-10 da rede eléctrica

TDI - Transdutores domóticos inteligentes

Relatório Final 97/276

5 – PROGRAMADOR PARA O MICROCONTROLADOR PIC16F877A

O esquema do programador utilizado neste projecto é da autoria de Henk Shaer, com um novo desenho do esquema eléctrico fornecido em ASCII[41] para fabricar a PCB. O esquema eléctrico e o respectivo negativo podem ser encontrado nos anexos.

A decisão para desenhar e montar este programador incidiu principalmente na sua velocidade de programação, preço, robustez e simplicidade de montagem.

O programador SCHAER[42] utiliza a porta paralela (LPT) do PC para a comunicação e baseia-se no método de programação série utilizando dois sinais (data e clock) para comunicar com o microcontrolador como descrito na datasheet DS30189A da Microchip.

Fig. 94 - Fotografias do Programador de PICs

Como software utilizou-se o IC-Prog[43], programa que permite programar quase todo o tipo de dispositivos desde que o hardware seja adequado.

A configuração do IC-Prog está descrita na Fig. 94.

TDI - Transdutores domóticos inteligentes

Relatório Final 98/276

Fig. 95 - Configuração do IC-Prog para o programador

TDI - Transdutores domóticos inteligentes

Relatório Final 99/276

6 – BOOTLOADER PARA O PIC16F877A

Por uma questão de comodidade, e maior rendimento, no desenvolvimento deste projecto (para que não seja necessário retirar o microcontrolador da placa sempre que é necessário reprogramar o IC), desenvolveu-se um bootloader que comunica com o PIC pela porta série (RS232).

Foram assim criados dois programas: O código para o microcontrolador e a respectiva aplicação gráfica para o PC.

6.1 PROGRAMA PARA O MICROCONTROLADOR

A estrutura do programa para o microcontrolador deve ser o mais simples possível pois, quanto maior for o código mais memória irá ocupar e assim, menos memória sobrará para o programa principal. Neste caso o programa requer por volta de 10% da capacidade total do microcontrolador o que já é significativo, mas suficiente para escrever os programas principais.

O bootloader recebe os dados linha por linha e de acordo com o formato do HEX[46] (Intel HEX-Record Format) processa-a, verifica o seu checksum e escreve na flash o respectivo programa.

O tratamento de erros não foi muito explorado, limitando-se ao mais importante, evitar sobreposição do bootloader e programa principal e a fiabilidade da transferência, como se descreve no esquema em baixo.

Fig. 96 - Diagrama da transmissão entre o PC e o microcontrolador

TDI - Transdutores domóticos inteligentes

Relatório Final 100/276

Segue-se um fluxograma simplificado do programa, onde não se frisa o tratamento de erros, processamento de dados nem a comunicação com a porta série.

Fig. 97 - Fluxograma do programa para o microcontrolador

6.2 APLICAÇÃO GRÁFICA PARA O PC

A aplicação gráfica para o PC foi desenvolvida recorrendo ao Borland Delphi 7 à semelhança da outra aplicação gráfica criada para interagir com o módulo “Interface para PC”. Também aqui utilizamos a biblioteca ComPort 3.0 para a comunicação série.

Esta aplicação permite que o utilizador carregue um ficheiro do tipo HEX-record, seleccione a porta COM em que o microcontrolador está ligado e claro, permite a respectiva programação.

TDI - Transdutores domóticos inteligentes

Relatório Final 101/276

Ao nível da transmissão, como já foi referido, no ponto anterior esta aplicação limita-se a ser um “escravo” do programa do microcontrolador, enviando as linhas a pedido.

Fig. 98 – Aplicação gráfica para o bootloader

TDI - Transdutores domóticos inteligentes

Relatório Final 102/276

7 – CONCLUSÕES

Podemos afirmar que os objectivos a que nos propusemos foram cumpridos apesar de terem sido enfrentadas inúmeras dificuldades.

Devido a um grande nível de ruído na rede da FEUP, causado pela imensa aparelhagem instalada foi-nos necessário alterar diversas vezes o hardware dimensionado. A pouca documentação existente sobre módulos assentes na tecnologia X-10 foi também um grande condicionante.

Apesar do sistema X-10 ter mais de 25 anos, continua a ser um protocolo de excelência para uso doméstico devido ao seu baixo custo e facilidade de instalação. Mas começam a surgir novas tecnologias (redes de banda larga, áudio/vídeo em tempo real) e aí este sistema torna-se limitado pois no que toca a velocidade de comunicação, o seu protocolo e meio de comunicação são um grande entrave.

Actualmente grandes empresas têm acreditado que é possível utilizar a rede eléctrica para obter transmissões de alto débito, tendo já sido lançados produtos para o mercado. Neste momento é já possível efectuar transferência de dados a uma velocidade máxima de 14Mbit/s.

O estudo de diversos protocolos demonstrou-nos que a área da domótica é ainda muito jovem e quase inexplorada. Para nós, a tendência num futuro próximo será o aparecimento de módulos dotados com inteligência artificial e com meios de comunicação sem fios (móveis) ou utilizando a própria alimentação para comunicar (fixos), podendo usufruir de todas as funcionalidades de banda larga.

TDI - Transdutores domóticos inteligentes

Relatório Final 103/276

8 - BIBLIOGRAFIA

[1] Alves, José Augusto e Mota, José; Casas inteligentes; Centro atlântico; 2003

[2] http://www.epanorama.net/links/automation.html

[3] http://www.ogc.be/hometelecare/hometelenet/articles/soce5002.html#a7

[4] http://www.x10.com/automation/x10_pl513.htm

[5] http://www.smarthomeforum.com/start/default.asp

[6] http://www.domoticaviva.com/temas.htm#Bricolaje

[7] http://www.domoticaviva.com/X-10/X-10.htm

[8] http://www.paedosexualitaet.de/pedo/transmission.html

[9] http://paginas.fe.up.pt/~ee99043/plm/x10tech.htm

[10] http://www.hometoys.com/htinews/jun98/articles/kingery/kingery9.htm

[11] http://www.act-solutions.com/uncle.htm

[12] http://www.geocities.com/ido_bartana

[13] http://www.lardocelar.com/consultorio/conssubarea.jsp?area=8&subarea=46

[14] http://www.iautomate.com/discus/messages/27/62.html?1034767035

[15] http://www.x10.com/support/basicx10.htm

[16] ftp://ftp.x10.com/pub/manuals/xtc798.doc

[17] http://www.georg-luber.de/

[18] http://www.eiba.com/downloads/downloads.nsf/system%20specifications

[19] Santos, Domingos Salvador Gonçalves; Apoio à concepção de sistemas domóticos EIB para pessoas com necessidades especiais; FEUP, 2001

[20] http://www.domesystems.co.uk/whatiseib.htm

[21] http://www.knx-developer.de/online/data/introduc.pdf

[22] http://conceitotecnologia.com.br/projetos/index_lonworks1.htm

[23] http://conceitotecnologia.com.br/projetos/index_lonworks2.htm

[24] http://www.echelon.com/products/lonworks/default.htm

TDI - Transdutores domóticos inteligentes

Relatório Final 104/276

[25] http://www.echelon.com/solutions/opensystems/papers/Control_Internet.pdf

[26] http://www.echelon.com/support/documentation/manuals/078-0183-01A.pdf

[27] http://us.st.com/stonline/books/pdf/docs/9546.pdf

[28] http://www.semiconductors.com/acrobat/datasheets/TDA5051<_2.pdf

[29] http://www.profec.com/

[30] http://www.profec.com/pdfs/data282x.pdf

[31] http://www.fairchildsemi.com/ds/6N/6N136.pdf

[32] http://www.fairchildsemi.com/ds/CD/CD4069UBC.pdf

[33] http://pdfserv.maxim-ic.com/en/ds/DS275.pdf

[34] http://web.ukonline.co.uk/j.winpenny/pic/rs232.txt

[35] http://massind.org/techref/microchip/16F877/pwm.htm

[36] http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf

[37] http://www.picant.com/c2c/examples/async/async_sample3.c.html

[38] http://pdfserv.maxim-ic.com/en/ds/DS12C887A.pdf

[39] http://pdfserv.maxim-ic.com/en/an/app516.pdf

[40] http://www.farnell.com/datasheets/45547.pdf

[41] http://home.att.net/~wzmicro/pic_link.htm

[42] http://www.geocities.com/SiliconValley/Way/5807/picprog.zip

[43] http://www.ic-prog.com/

[44] http://ww1.microchip.com/downloads/en/AppNotes/00732a.pdf

[45] http://www.gogoboard.org

[46] http://www.cs.net/lucid/intel.htm

[47] http://sourceforge.net/projects/comport/

[48] http://www.borland.com/delphi/

[49] http://www.ccsinfo.com/picc.shtml

[50] [50] http://ww1.microchip.com/downloads/en/AppNotes/00236a.pdf

TDI - Transdutores domóticos inteligentes

Relatório Final 105/276

9 - ANEXOS

ANEXO A - CÓDIGO FONTE DOS MÓDULOS

Livrarias comuns a todos os módulos

Livraria interface.h

#include <16F877A.h> #use delay(clock=7680000) #fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP

Livraria x10func.h

// Completa e efectua a rotação de um numero de 8 bits int16 X10rotANDcompl(char value) { int i; int16 result; result = 0; for (i=0; i < 8; i++) { if (((value >> i) & 0x01) == 1) result = (result << 1) + 0b0; else result = (result << 1) + 0b1; result = (result << 1) + ((int16) ((value >> i) & 0x01)); } return result; } // Retira o complemento de um numero de 16 bits char X10decompl(int16 value) { int i; char result; result = 0; for (i=8; i > 0; i--) { if (((value >> (i * 2 - 1)) & 0x01) == 1)

TDI - Transdutores domóticos inteligentes

Relatório Final 106/276

result = (result << 1) + 0b1; else result = (result << 1) + 0b0; } return result; } //Efectua a codificação para enviar dados (ler o return de tras para a frente) char encodeX10(char code, char type) { // HC - A | UC - 1 | DC - All Lights Off if ((code==1 && type == 'U') || (code=='A' && type == 'H') || (code==7 && type == 'D')) return 0b10010110; // HC - B | UC - 2 | DC - Status "OFF" else if ((code==2 && type == 'U') || (code=='B' && type == 'H') || (code==15 && type == 'D')) return 0b10010101; // HC - C | UC - 3 | DC - On else if ((code==3 && type == 'U') || (code=='C' && type == 'H') || (code==1 && type == 'D')) return 0b10011010; // HC - D | UC - 4 | DC - Extended Code 3 else if ((code==4 && type == 'U') || (code=='D' && type == 'H') || (code==11 && type == 'D')) return 0b10011001; // HC - E | UC - 5 | DC - ALL LIGHTS ON else if ((code==5 && type == 'U') || (code=='E' && type == 'H') || (code==5 && type == 'D')) return 0b01101010; // HC - F | UC - 6 | DC - HAIL ACK else if ((code==6 && type == 'U') || (code=='F' && type == 'H') || (code==10 && type == 'D')) return 0b01101001; // HC - G | UC - 7 | DC - BRIGHT else if ((code==7 && type == 'U') || (code=='G' && type == 'H') || (code==4 && type == 'D')) return 0b01100110; // HC - H | UC - 8 | DC - STATUS "ON" else if ((code==8 && type == 'U') || (code=='H' && type == 'H') || (code==14 && type == 'D')) return 0b01100101; // HC - I | UC - 9 | DC - Extended Code 1 else if ((code==9 && type == 'U') || (code=='I' && type == 'H') || (code==8 && type == 'D')) return 0b01010110; // HC - J | UC - 10 | DC - Status Request else if ((code==10 && type == 'U') || (code=='J' && type == 'H') || (code==16 && type == 'D')) return 0b01010101; // HC - K | UC - 11 | DC - OFF else if ((code==11 && type == 'U') || (code=='K' && type == 'H') || (code==2 && type == 'D')) return 0b01011010; // HC - L | UC - 12 | DC - UNUSED else if ((code==12 && type == 'U') || (code=='L' && type == 'H') || (code==12 && type == 'D')) return 0b01011001; // HC - M | UC - 13 | DC - ALL UNITS OFF

TDI - Transdutores domóticos inteligentes

Relatório Final 107/276

else if ((code==13 && type == 'U') || (code=='M' && type == 'H') || (code==6 && type == 'D')) return 0b10101010; // HC - N | UC - 14 | DC - HAIL REQUEST else if ((code==14 && type == 'U') || (code=='N' && type == 'H') || (code==9 && type == 'D')) return 0b10101001; // HC - O | UC - 15 | DC - DIM else if ((code==15 && type == 'U') || (code=='O' && type == 'H') || (code==3 && type == 'D')) return 0b10100110; // HC - P | UC - 16 | DC - Extended Code 2 else if ((code==16 && type == 'U') || (code=='P' && type == 'H') || (code==13 && type == 'D')) return 0b10100101; else if (code==255 && type == 'U') return 255; else return 0b00000000; } // Descodifica o codigo recebido pela rede char decodeX10(char code, char type) { if (code == 0b01101001) // HC - A | UC - 1 | DC - All Lights Off { if (type == 'H') return 'A'; else if (type == 'D') return 7; else if (type == 'U') return 1; } else if (code == 0b10101001) // HC - B | UC - 2 | DC - Status "OFF" { if (type == 'H') return 'B'; else if (type == 'D') return 15; else if (type == 'U') return 2; } else if (code == 0b01011001) // HC - C | UC - 3 | DC - On { if (type == 'H') return 'C'; if (type == 'D') return 1; else if (type == 'U') return 3; } else if (code == 0b10011001) // HC - D | UC - 4 | DC - Extended Code 3 { if (type == 'H') return 'D'; if (type == 'D') return 11; else if (type == 'U') return 4; }

TDI - Transdutores domóticos inteligentes

Relatório Final 108/276

else if (code == 0b01010110) // HC - E | UC - 5 | DC - ALL LIGHTS ON { if (type == 'H') return 'E'; if (type == 'D') return 5; else if (type == 'U') return 5; } else if (code == 0b10010110) // HC - F | UC - 6 | DC - HAIL ACK { if (type == 'H') return 'F'; if (type == 'D') return 10; else if (type == 'U') return 6; } else if (code == 0b01100110) // HC - G | UC - 7 | DC - BRIGHT { if (type == 'H') return 'G'; if (type == 'D') return 4; else if (type == 'U') return 7; } else if (code == 0b10100110) // HC - H | UC - 8 | DC - STATUS "ON" { if (type == 'H') return 'H'; if (type == 'D') return 14; else if (type == 'U') return 8; } else if (code == 0b01101010) // HC - I | UC - 9 | DC - Extended Code 1 { if (type == 'H') return 'I'; if (type == 'D') return 8; else if (type == 'U') return 9; } else if (code == 0b10101010) // HC - J | UC - 10 | DC - Status Request { if (type == 'H') return 'J'; if (type == 'D') return 16; else if (type == 'U') return 10; } else if (code == 0b01011010) // HC - K | UC - 11 | DC - OFF { if (type == 'H') return 'K'; if (type == 'D') return 2; else if (type == 'U') return 11; }

TDI - Transdutores domóticos inteligentes

Relatório Final 109/276

else if (code == 0b10011010) // HC - L | UC - 12 | DC - UNUSED { if (type == 'H') return 'L'; if (type == 'D') return 12; else if (type == 'U') return 12; } else if (code == 0b01010101) // HC - M | UC - 13 | DC - ALL UNITS OFF { if (type == 'H') return 'M'; if (type == 'D') return 6; else if (type == 'U') return 13; } else if (code == 0b10010101) // HC - N | UC - 14 | DC - HAIL REQUEST { if (type == 'H') return 'N'; if (type == 'D') return 9; else if (type == 'U') return 14; } else if (code == 0b01100101) // HC - O | UC - 15 | DC - DIM { if (type == 'H') return 'O'; if (type == 'D') return 3; else if (type == 'U') return 15; } else if (code == 0b10100101) // HC - P | UC - 16 | DC - Extended Code 2 { if (type == 'H') return 'P'; if (type == 'D') return 13; else if (type == 'U') return 16; } else { if (type == 'H') return 255; if (type == 'D') return 255; else if (type == 'U') return 255; } } // Verficica complemento para numero de 8 bits char check8(char c) {

TDI - Transdutores domóticos inteligentes

Relatório Final 110/276

int a, b; a = c & 0x55; b = (c >> 1) & 0x55; if ((a ^ b) == 0x55) return 0; else return 1; } // Verficica complemento para numero de 4 bits char check4(char c) { int a, b; a = c & 0x05; b = (c >> 1) & 0x05; if ((a ^ b) == 0x05) return 0; else return 1; } // Coloca em TxBuffer1 e TxBuffer2 o comando a enviar e da ordens para isso void sendX10(int1 extended, int1 spccode, char HC, char UC, char DC, int16 ExtDC, int16 ExtCC) { if (extended == 0) { TxBuffer1 = (0b10 << 20) + ((int32) encodeX10(UC,'U') << 12) + ((int32) encodeX10(HC,'H') << 4) + 0b0111; TxBuffer2 = (0b01 << 20) + ((int32) encodeX10(DC,'D') << 12) + ((int32) encodeX10(HC,'H') << 4) + 0b0111; TxExtCode = 0; } else { TxBuffer1 = ((int32) encodeX10(UC,'U') << 22) + (0b0101010110 << 12) + ((int32) encodeX10(HC,'H') << 4) + 0b0111; TxBuffer2 = ((int32) X10rotANDcompl(ExtCC) << 16) + ((int32) X10rotANDcompl(ExtDC)); TxExtCode = 1; } if (spccode == 1) TxSpcCode = 1; else TxSpcCode = 0; TxCount = 0; TxState = 0; TxBusy = 1; }

TDI - Transdutores domóticos inteligentes

Relatório Final 111/276

Código fonte do módulo “Interface para PC”

Livraria misc.h

// Acesso directo aos registos #bit T0IF = 0x0b.2 #bit X10IN = 0x06.1 #bit INTEDG = 0x81.6 int save_w; #locate save_w=0x7f int save_status; #locate save_status=0x20 #byte status = 3 int const BufferSize = 13; // Transmissão int32 TxBuffer1, TxBuffer2; int1 TxExtCode, TxSpcCode; int TxCount; int1 TxBusy; char TxState; // 0 - Primeiro HC UC // 1 - Segundo HC UC // 2 - Wait 4 cycles // 3 - Primeiro HC AC // 4 - Segundo HC AC // 5 - End char TxPhase; int1 TxStopPWM; char W8hc; // wait 8 half cycles // Recepção char RxStartCode; char RxBuffer1; int16 RxBuffer2; char RxError[2]; char RxHC[2]; char RxDC[2]; char RxFC[2];

TDI - Transdutores domóticos inteligentes

Relatório Final 112/276

char RxExtDC[2]; char RxExtData[2]; char RxExtCommand[2]; char RxState; char RxExtended; char RxCounter; char RxOk; char RxComplete; // Porta Serie int1 RSdataRec; int1 RSdataToSend; char RSbuffer; char RScount; char RSRxcommand[BufferSize]; char RSTxcommand[BufferSize]; // Imprime pela porta rs232 em formato binario void printbin(char c) { int i; i = 7; while (i!=-1) { if (((c >> i) & 0x01) == 1) putc('1'); else putc('0'); i--; } } Programa Principal – interface.c #include "interface.h" #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #include "misc.h" #include "x10func.h" void X10Transmit(); void StartPWM(void); void X10Receive(int1 RxBit); void X10TermTx(void);

TDI - Transdutores domóticos inteligentes

Relatório Final 113/276

// Interrupção INT0 - Detecção dos zeros #int_EXT EXT_isr() { #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm // Alterna o tipo de disparo da interrupção - L->H e H->L INTEDG ^=1; // Transmissão if ( (TxBusy == 1) && (w8hc > 8) ) { X10Transmit(); } // Recepção else { set_timer0(0xE2); T0IF = 0; enable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } // Interrupção do TIMER #int_RTCC RTCC_isr() {

TDI - Transdutores domóticos inteligentes

Relatório Final 114/276

int i; #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm // Envia para no sistema trifasico if ((TxBusy == 1) && (w8hc > 8) ) { // Activa a PWM para as outras fases if ((TxStopPWM == 0) && (TxPhase >= 1)) StartPWM(); else { TxStopPWM = 0; setup_ccp1(CCP_OFF); disable_interrupts(INT_RTCC); if (TxPhase < 3) { set_timer0(0xBC); T0IF = 0; enable_interrupts(INT_RTCC); } if (TxPhase >= 3) TxPhase = 0; } } // Recepcao else { if (X10IN == 0) { X10Receive(X10IN); // Espera por 8 meios ciclos if (w8hc <= 8) w8hc++; } else { // Detectou actividade na rede w8hc = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 115/276

X10Receive(X10IN); } // Envia dados pela porta serie if (RSdataToSend == 1) { RSdataToSend = 0; i=0; do { putc(RSTxCommand[i]); i++; } while (RSTxCommand[i-1] != 23); } disable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } // Envia SENT para o PC quando envia dados void X10TermTx(void) { TxBuffer1 = 0; TxBuffer2 = 0; TxBusy = 0; TxCount = 0; TxState = 0; TxExtCode = 0; TxSpcCode = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 116/276

RSTxCommand[0]=22;RSTxCommand[1]=1;RSTxCommand[2]='S';RSTxCommand[3]='E'; RSTxCommand[4]='N';RSTxCommand[5]='T';RSTxCommand[6]=23; RSdataToSend=1; } // Activa a PWM e define o timer para a sua duração void StartPWM(void) { setup_ccp1(CCP_PWM); set_timer0(0xDF); T0IF = 0; enable_interrupts(INT_RTCC); TxPhase++; TxStopPWM = 1; } //Funcao responsavel pela transmissão correcta dos dados void X10Transmit() { if (TxExtCode == 0) { // Caso do Special Codes, tipo DIM e BRIGHT if ((TxSpcCode == 1) && (TxState == 0)) TxState = 3; if ((TxCount < 22) && (TxState <= 1)) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } // espera o 8 half cycles (TxCount em 255 para impedir ke quando esperou os 8 hc volte a esta condicao else if ((TxCount != 255) && (TxState == 2)) { w8hc = 0; TxCount = 255; } else if ((TxCount < 22) && ( (TxState >= 3) && (TxState <= 4))) { if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 5) X10TermTx(); // Determina as passagens para o outro estado if ( ((TxCount == 22) && (TxState <= 1)) || ((w8hc > 8) && (TxState == 2)) || ((TxCount == 22) && ((TxState >= 3) && (TxState <= 4)) ) ) { TxState++; TxCount = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 117/276

} } // Codigo Extendido else { if (((TxCount < 30) && (TxState == 0)) || ((TxCount < 30) && (TxState == 2))) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (((TxCount < 32) && (TxState == 1)) || ((TxCount < 32) && (TxState == 3))){ if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 4) X10TermTx(); if ( ((TxCount == 30) && ((TxState == 0) || (TxState == 2))) || ((TxCount == 32) && ((TxState == 1) || (TxState == 3)))) { TxState++; TxCount = 0; } } } // Funcao responsavel pela recepção correcta dos dados void X10Receive(int1 RxBit) { if (RxStartCode != 0x0E) { // 1110 RxStartCode = RxStartCode << 1; if (RxBit == 1) RxStartCode |= 0x01; RxStartCode &= 0x0F; if (RxStartCode == 0x0E) { RxCounter = 0; RxBuffer1 = 0; RxBuffer2 = 0; RxError[0]=0; RxError[1]=0; } }

TDI - Transdutores domóticos inteligentes

Relatório Final 118/276

else if (RxStartCode == 0x0E) { if (RxCounter < 8) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 7) { RxError[RxState] += check8(RxBuffer1); RxHC[RxState] = decodeX10(RxBuffer1, 'H'); } } else if ((RxCounter >=8) && (RxCounter < 16)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 15) { RxError[RxState] += check8(RxBuffer1); } } else if ((RxCounter >=16) && (RxCounter < 18)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 17) { if (RxBuffer2 == 0x01) { RxDC[RxState] = decodeX10(RxBuffer1, 'U'); RxFC[RxState] = 1;} else if (RxBuffer2 == 0x02) { RxDC[RxState] = decodeX10(RxBuffer1, 'D'); RxFC[RxState] = 2; } else RxError[RxState] += 1; if ((RxDC[RxState] == 8) && (RxFC[RxState] == 2)) {} // Caso n seja um extended code else { RxStartCode=0; if (RxState == 1) { RxState = 0; if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 1; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk];

TDI - Transdutores domóticos inteligentes

Relatório Final 119/276

RxFC[0]=RxFC[RxOk]; } } else RxState = 1; } } } else if ((RxCounter >=18) && (RxCounter < 26)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 25) { RxError[RxState] += check8(RxBuffer1); RxExtDC[RxState] = decodeX10(RxBuffer1, 'U'); } } else if ((RxCounter >=26) && (RxCounter < 42)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 41) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtData[RxState] = X10decompl(RxBuffer2); } } else if ((RxCounter >=42) && (RxCounter < 58)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 57) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtCommand[RxState] = X10decompl(RxBuffer2); RxStartCode=0; if (RxState == 1) { if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 2; RxHC[0]=RxHC[RxOk];

TDI - Transdutores domóticos inteligentes

Relatório Final 120/276

RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; RxExtDC[0]=RxExtDC[RxOk]; RxExtData[0] = RxExtData[RxOk]; RxExtCommand[0] = RxExtCommand[RxOk]; } RxState = 0; } else RxState = 1; } } RxCounter++; } } void main() { //Configura microcontrolador setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_1(T1_DISABLED); setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL); setup_timer_2(T2_DIV_BY_4, 3, 1); set_pwm1_duty(2); setup_ccp1(CCP_OFF); printf("PC Module\r\n"); set_tris_b(0x0F); // Inicialização de variaveis INTEDG = 0; w8hc = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 121/276

TxBusy = 0; TxState = 0; TxPhase = 0; TxStopPWM = 0; RxComplete = 0; RxStartCode = 0; RxState = 0; RSdataRec = 0; RScount = 0; RSdataToSend = 0; RSdataRec = 0; disable_interrupts(INT_RTCC); enable_interrupts(INT_EXT); enable_interrupts(global); // Ciclo infinito while(TRUE) { // Quando sao recebidos dados da rede if (RxComplete == 1) { RxComplete = 0; putc(22); putc(2); putc(RxExtended); putc(RxHC[0]); if (RxExtended == 1) { putc(RxDC[0]); putc(RxFC[0]); } else { putc(RxExtDC[0]); putc(RxExtData[0]); putc(RxExtCommand[0]); } putc(23); } // Quando microdesocupado... nao esta a enviar dados if (TxBusy == 0) { if (kbhit()) { RSbuffer = getc();

TDI - Transdutores domóticos inteligentes

Relatório Final 122/276

if (RSbuffer == 22) { RScount=0; RSRxcommand[RScount]=RSbuffer; } else if (RSbuffer == 23) { RScount++; RSRxcommand[RScount]=RSbuffer; RSdataRec = 1; } else { RScount++; RSRxcommand[RScount]=RSbuffer; } } if (RSdataRec == 1) { // Pergunta Interna ao Modulo if (RSRxcommand[1] == 1) { if ((RSRxcommand[2] == 'C') && (RSRxcommand[3] == 'O') && (RSRxcommand[4] == 'N') && (RSRxcommand[5] == 'N') && (RSRxcommand[6] == 'E') && (RSRxcommand[7] == 'C') && (RSRxcommand[8] == 'T')) { RSTxCommand[0]=22;RSTxCommand[1]=1;RSTxCommand[2]='C';RSTxCommand[3]='O';RSTxCommand[4]='N';RSTxCommand[5]='N'; RSTxCommand[6]='E';RSTxCommand[7]='C';RSTxCommand[8]='T';RSTxCommand[9]=' ';RSTxCommand[10]='O';RSTxCommand[11]='K'; RSTxCommand[12]=23; RSdataToSend=1; } } else if (RSRxcommand[1] == 2) { // Codigo normal if (RSRxcommand[2] == 1) { if ((RSRxcommand[3] >=65 && RSRxcommand[3] <=80) && ((RSRxcommand[4] >= 1 && RSRxcommand[4] <= 16) || RSRxcommand[4] == 255) && (RSRxcommand[5] >= 1 && RSRxcommand[5] <= 16)) { TxBuffer1 = (0b10 << 20) + ((int32) encodeX10(RSRxcommand[4],'U') << 12) + ((int32) encodeX10(RSRxcommand[3],'H') << 4) + 0b0111; TxBuffer2 = (0b01 << 20) + ((int32) encodeX10(RSRxcommand[5],'D') << 12) + ((int32) encodeX10(RSRxcommand[3],'H') << 4) + 0b0111; if (RSRxcommand[4] == 255) TxSpcCode = 1; else TxSpcCode = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 123/276

TxExtCode = 0; TxCount = 0; TxState = 0; TxBusy = 1; } } // Codigo Extendido else if (RSRxcommand[2] == 2) { TxBuffer1 = ((int32) encodeX10(RSRxcommand[4],'U') << 22) + (0b0101010110 << 12) + ((int32) encodeX10(RSRxcommand[3],'H') << 4) + 0b0111; TxBuffer2 = ((int32) X10rotANDcompl(RSRxcommand[6]) << 16) + ((int32) X10rotANDcompl(RSRxcommand[5])); TxExtCode = 1; TxCount = 0; TxState = 0; TxBusy = 1; } } RSdataRec = 0; } } } } Código fonte do modulo “Sensor” Livraria misc.h // Acesso directo aos registos #bit T0IF = 0x0b.2 #bit X10IN = 0x06.1 #bit INTEDG = 0x81.6 #bit SENSOR = 0x06.2 int save_w; #locate save_w=0x7f int save_status; #locate save_status=0x20 #byte status = 3

TDI - Transdutores domóticos inteligentes

Relatório Final 124/276

int const BufferSize = 13; char ModuleHC, ModuleUC; int1 ModuleEnable; int1 last_state; // Transmissão int32 TxBuffer1, TxBuffer2; int1 TxExtCode, TxSpcCode; int TxCount; int1 TxBusy; char TxState; // 0 - Primeiro HC UC // 1 - Segundo HC UC // 2 - Wait 4 cycles // 3 - Primeiro HC AC // 4 - Segundo HC AC // 5 - End char TxPhase; int1 TxStopPWM; char W8hc; // wait 8 half cycles char SerialNConfig; // Recepção char RxStartCode; char RxBuffer1; int16 RxBuffer2; char RxError[2]; char RxHC[2]; char RxDC[2]; char RxFC[2]; char RxExtDC[2]; char RxExtData[2]; char RxExtCommand[2]; char RxState; char RxExtended; char RxCounter; char RxOk; char RxComplete; // Porta Serie int1 RSdataRec; int1 RSdataToSend; char RSbuffer; char RScount;

TDI - Transdutores domóticos inteligentes

Relatório Final 125/276

char RSRxcommand[BufferSize]; char RSTxcommand[BufferSize]; void printbin(char c) { int i; i = 7; while (i!=-1) { if (((c >> i) & 0x01) == 1) putc('1'); else putc('0'); i--; } } printEeprom(int offset) { int i,j; for (i=0; i<=offset; i=i+8) { printf("%x\t :", i); for (j=0; j<=7; j++) printf(" %x", read_eeprom(i+j)); printf("\r\n"); if (i == 0xA0) {printf("---- More ----\r\n"); getc();} if (i==0xF8) break; } } // Retorna o numero de serie do modulo int16 getModuleId(void) { return ((int16)read_eeprom(0x00) << 8) + read_eeprom(0x01); } // Grava na EEPROM o numero de serie do modulo void SetModuleId(int16 value) { write_eeprom(0x0000, (int) (value >> 8)); write_eeprom(0x0001, (int) value); }

TDI - Transdutores domóticos inteligentes

Relatório Final 126/276

// Retorna o HC do modulo char getHC(void) { return read_eeprom(0x02); } // Retorna o UC do modulo char getUC(void) { return read_eeprom(0x03); } // Grava o HC do modulo void setHC(char HC) { write_eeprom(0x0002, HC); } // Grava o UC do modulo void setUC(char UC) { write_eeprom(0x0003, UC); } // Grava o UC a enviar para actuar void setSensorUC(char SensorUC) { write_eeprom(0x0004, SensorUC); } // Retorna o UC a enviar para actuar char getSensorUC(void) { return read_eeprom(0x04); } // Grava o comando a enviar para actuar void setSensorCommand(char SensorCommand) { write_eeprom(0x0005, SensorCommand); } // Retorna o comando a enviar para actuar char getSensorCommand(void) { return read_eeprom(0x05);

TDI - Transdutores domóticos inteligentes

Relatório Final 127/276

} Código principal – interface.c #include "interface.h" #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #include "misc.h" #include "D:\Domotica\PIC Programming\x10func.h" void X10Transmit(); void StartPWM(void); void X10Receive(int1 RxBit); void X10TermTx(void); // Interrupção INT0 - Detecção dos zeros #int_EXT EXT_isr() { #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm // Alterna o tipo de disparo da interrupção - L->H e H-> INTEDG ^=1; // Transmissão if ( (TxBusy == 1) && (w8hc > 8) ) { X10Transmit(); } // Recepção else { set_timer0(0xE2); T0IF = 0; enable_interrupts(INT_RTCC); }

TDI - Transdutores domóticos inteligentes

Relatório Final 128/276

#asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } // Interrupção do TIMER #int_RTCC RTCC_isr() { int i; #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm // Envia para no sistema trifasico if ((TxBusy == 1) && (w8hc > 8) ) { // Activa a PWM para as outras fases if ((TxStopPWM == 0) && (TxPhase >= 1)) StartPWM(); else { TxStopPWM = 0; setup_ccp1(CCP_OFF); disable_interrupts(INT_RTCC); if (TxPhase < 3) { set_timer0(0xBC); T0IF = 0; enable_interrupts(INT_RTCC); } if (TxPhase >= 3) TxPhase = 0; }

TDI - Transdutores domóticos inteligentes

Relatório Final 129/276

} // Recepcao else { if (X10IN == 0) { X10Receive(X10IN); // Espera por 8 meios ciclos if (w8hc <= 8) w8hc++; } else { // Detectou actividade na rede w8hc = 0; X10Receive(X10IN); } disable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } //Termina transmissão void X10TermTx(void) { TxBuffer1 = 0; TxBuffer2 = 0; TxBusy = 0; TxCount = 0; TxState = 0; TxExtCode = 0; TxSpcCode = 0; } // Activa a PWM e define o timer para a sua duração void StartPWM(void) { setup_ccp1(CCP_PWM);

TDI - Transdutores domóticos inteligentes

Relatório Final 130/276

set_timer0(0xDF); T0IF = 0; enable_interrupts(INT_RTCC); TxPhase++; TxStopPWM = 1; } //Funcao responsavel pela transmissão correcta dos dados void X10Transmit() { if (TxExtCode == 0) { // Caso do Special Codes, tipo DIM e BRIGHT if ((TxSpcCode == 1) && (TxState == 0)) TxState = 3; if ((TxCount < 22) && (TxState <= 1)) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } // espera o 8 half cycles (TxCount em 255 para impedir ke quando esperou os 8 hc volte a esta condicao else if ((TxCount != 255) && (TxState == 2)) { w8hc = 0; TxCount = 255; } else if ((TxCount < 22) && ( (TxState >= 3) && (TxState <= 4))) { if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 5) X10TermTx(); // Determina as passagens para o outro estado if ( ((TxCount == 22) && (TxState <= 1)) || ((w8hc > 8) && (TxState == 2)) || ((TxCount == 22) && ((TxState >= 3) && (TxState <= 4)) ) ) { TxState++; TxCount = 0; } } // Codigo Extendido else { if (((TxCount < 30) && (TxState == 0)) || ((TxCount < 30) && (TxState == 2))) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (((TxCount < 32) && (TxState == 1)) || ((TxCount < 32) && (TxState == 3))){ if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM();

TDI - Transdutores domóticos inteligentes

Relatório Final 131/276

TxCount++; } else if (TxState == 4) X10TermTx(); if ( ((TxCount == 30) && ((TxState == 0) || (TxState == 2))) || ((TxCount == 32) && ((TxState == 1) || (TxState == 3)))) { TxState++; TxCount = 0; } } } // Funcao responsavel pela recepção correcta dos dados void X10Receive(int1 RxBit) { if (RxStartCode != 0x0E) { // 1110 RxStartCode = RxStartCode << 1; if (RxBit == 1) RxStartCode |= 0x01; RxStartCode &= 0x0F; if (RxStartCode == 0x0E) { RxCounter = 0; RxBuffer1 = 0; RxBuffer2 = 0; RxError[0]=0; RxError[1]=0; } } else if (RxStartCode == 0x0E) { if (RxCounter < 8) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 7) { RxError[RxState] += check8(RxBuffer1); RxHC[RxState] = decodeX10(RxBuffer1, 'H'); } } else if ((RxCounter >=8) && (RxCounter < 16)) { RxBuffer1 <<= 1;

TDI - Transdutores domóticos inteligentes

Relatório Final 132/276

if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 15) { RxError[RxState] += check8(RxBuffer1); } } else if ((RxCounter >=16) && (RxCounter < 18)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 17) { if (RxBuffer2 == 0x01) { RxDC[RxState] = decodeX10(RxBuffer1, 'U'); RxFC[RxState] = 1;} else if (RxBuffer2 == 0x02) { RxDC[RxState] = decodeX10(RxBuffer1, 'D'); RxFC[RxState] = 2; } else RxError[RxState] += 1; if ((RxDC[RxState] == 8) && (RxFC[RxState] == 2)) {} // Caso n seja um extended code else { RxStartCode=0; if (RxState == 1) { RxState = 0; if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 1; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; } } else RxState = 1; } } } //codigo extendido else if ((RxCounter >=18) && (RxCounter < 26)) {

TDI - Transdutores domóticos inteligentes

Relatório Final 133/276

RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 25) { RxError[RxState] += check8(RxBuffer1); RxExtDC[RxState] = decodeX10(RxBuffer1, 'U'); } } else if ((RxCounter >=26) && (RxCounter < 42)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 41) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtData[RxState] = X10decompl(RxBuffer2); } } else if ((RxCounter >=42) && (RxCounter < 58)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 57) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtCommand[RxState] = X10decompl(RxBuffer2); RxStartCode=0; if (RxState == 1) { if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 2; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; RxExtDC[0]=RxExtDC[RxOk]; RxExtData[0] = RxExtData[RxOk]; RxExtCommand[0] = RxExtCommand[RxOk]; } RxState = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 134/276

} else RxState = 1; } } RxCounter++; } } void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_1(T1_DISABLED); setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL); setup_timer_2(T2_DIV_BY_4, 3, 1); set_pwm1_duty(2); setup_ccp1(CCP_OFF); set_tris_b(0x0F); set_tris_d(0x00); set_tris_c(0x80); //1000 0000 printf("Sensor Module\r\n"); // Numero de serie do modulo SetModuleId(0x1003); ModuleHC = getHC(); ModuleUC = getUC(); ModuleEnable = 0; last_state = SENSOR; // Inicialização de variaveis

TDI - Transdutores domóticos inteligentes

Relatório Final 135/276

INTEDG = 0; w8hc = 0; TxBusy = 0; TxState = 0; TxPhase = 0; TxStopPWM = 0; RxComplete = 0; RxStartCode = 0; RxState = 0; SerialNConfig = 0; disable_interrupts(INT_RTCC); enable_interrupts(INT_EXT); enable_interrupts(global); while(TRUE) { // Quando sao recebidos dados da rede if (RxComplete == 1) { RxComplete = 0; printf("%d ",RxExtended); putc(RxHC[0]); if (RxExtended == 1) { printf("%d ", RxDC[0]); printf("%d ", RxFC[0]); } else { printf("%d ", RxExtDC[0]); printf("%d ", RxExtData[0]); printf("%d ", RxExtCommand[0]); } // Activa modulo caso comando recebido seja para ele if (RxExtended == 1) { if ((RxFC[0] == 1) && (RxHC[0] == ModuleHC) && (RxDC[0] == ModuleUC)) ModuleEnable = 1;

TDI - Transdutores domóticos inteligentes

Relatório Final 136/276

else if (RxFC[0] == 1) ModuleEnable = 0; } else if (RxExtended == 2) { if ( (RxExtCommand[0] == 0x61) && (RxExtData[0] == (getModuleId() & 0xFF)) ) SerialNConfig++; else if ( (RxExtCommand[0] == 0x62) && (RxExtData[0] == ((getModuleId() >> 8) & 0xFF)) ) SerialNConfig++; else SerialNConfig=0; if ((RxHC[0] == ModuleHC) && (RxExtDC[0] == ModuleUC)) ModuleEnable = 1; } //Altera HC e UC via serial Number if (SerialNConfig == 2) { SerialNConfig = 0; setHC(RxHC[0]); setUC(RxExtDC[0]); ModuleHC = getHC(); ModuleUC = getUC(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } else if ((RxExtended == 2) && (ModuleEnable == 1)) { // Change HC e UC if (RxExtCommand[0] == 0x63) { setHC(((RxExtData[0] >> 4) & 0x0F) + 65); setUC((RxExtData[0] & 0x0F) + 1); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma ModuleHC = getHC(); ModuleUC = getUC(); } //Change Sensor settings if (RxExtCommand[0] == 0x64) { setSensorUC((RxExtData[0] >> 3) & 0x1F); setSensorCommand(RxExtData[0] & 0x07); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma // printf("%d %d", getSensorUC(), getSensorCommand()); } } else if ((RxHC[0] == ModuleHC) && (RxFC[0] == 2) && (ModuleEnable == 1)) { switch (RxDC[0]) {

TDI - Transdutores domóticos inteligentes

Relatório Final 137/276

case 9 : { // Hail Request sendX10(0, 0, ModuleHC, ModuleUC, 10, 0, 0); //HAIL ACK break; } case 16 : { // Status Request if (SENSOR == 0) sendX10(0, 0, ModuleHC, ModuleUC, 14, 0, 0); // Status ON else sendX10(0, 0, ModuleHC, ModuleUC, 15, 0, 0); // Status OFF break; } default : break; } } } if (TxBusy == 0) { if ((SENSOR == 0) && (last_state!=SENSOR)) if ((SENSOR == 0) && (last_state!=SENSOR)) { last_state = SENSOR; putc('x'); sendX10(0, 0, ModuleHC, getSensorUC(), getSensorCommand(), 0, 0); } else last_state = SENSOR; if (kbhit()) { RSBuffer = getc(); if (RSBuffer == '1') { disable_interrupts(INT_EXT); printf("%c%d", GetHC(), GetUC()); enable_interrupts(INT_EXT);

TDI - Transdutores domóticos inteligentes

Relatório Final 138/276

} } } } } Código fonte do modulo “Central de Inundação” Livraria misc.h // Acesso directo aos registos #bit T0IF = 0x0b.2 #bit X10IN = 0x06.1 #bit INTEDG = 0x81.6 #bit SENSOR_Z1 = 0x06.2 #bit SENSOR_Z2 = 0x06.3 #bit SENSOR_Z3 = 0x06.4 #bit SENSOR_Z4 = 0x06.5 #bit BUTTON = 0x06.6 #bit BUZZER = 0x08.0 #bit LED_Z1 = 0x08.1 #bit LED_Z2 = 0x08.2 #bit LED_Z3 = 0x08.3 #bit LED_Z4 = 0x08.4 #bit LED_SB = 0x08.5 #bit LED_ACTIVE = 0x08.6 int save_w; #locate save_w=0x7f int save_status; #locate save_status=0x20

TDI - Transdutores domóticos inteligentes

Relatório Final 139/276

#byte status = 3 int const BufferSize = 13; char ModuleHC, ModuleUC; int1 ModuleEnable; int1 last_state, sentCommand; int TCounter500ms, TCounter1s, Tcounter1min, SBWait; int1 TUpdate; char ZoneState; int1 SystemActive, SystemAlarm; // Transmissão int32 TxBuffer1, TxBuffer2; int1 TxExtCode, TxSpcCode; int TxCount; int1 TxBusy; char TxState; // 0 - Primeiro HC UC // 1 - Segundo HC UC // 2 - Wait 4 cycles // 3 - Primeiro HC AC // 4 - Segundo HC AC // 5 - End char TxPhase; int1 TxStopPWM; char W8hc; // wait 8 half cycles char SerialNConfig; // Recepção char RxStartCode; char RxBuffer1; int16 RxBuffer2; char RxError[2]; char RxHC[2]; char RxDC[2]; char RxFC[2]; char RxExtDC[2]; char RxExtData[2]; char RxExtCommand[2]; char RxState; char RxExtended;

TDI - Transdutores domóticos inteligentes

Relatório Final 140/276

char RxCounter; char RxOk; char RxComplete; // Porta Serie int1 RSdataRec; int1 RSdataToSend; char RSbuffer; char RScount; char RSRxcommand[BufferSize]; char RSTxcommand[BufferSize]; void printbin(char c) { int i; i = 7; while (i!=-1) { if (((c >> i) & 0x01) == 1) putc('1'); else putc('0'); i--; } } printEeprom(int offset) { int i,j; for (i=0; i<=offset; i=i+8) { printf("%x\t :", i); for (j=0; j<=7; j++) printf(" %x", read_eeprom(i+j)); printf("\r\n"); if (i == 0xA0) {printf("---- More ----\r\n"); getc();} if (i==0xF8) break; } } int16 getModuleId(void) { return ((int16)read_eeprom(0x00) << 8) + read_eeprom(0x01); } void SetModuleId(int16 value) {

TDI - Transdutores domóticos inteligentes

Relatório Final 141/276

write_eeprom(0x0000, (int) (value >> 8)); write_eeprom(0x0001, (int) value); } char getHC(void) { return read_eeprom(0x02); } char getUC(void) { return read_eeprom(0x03); } void setHC(char HC) { write_eeprom(0x0002, HC); } void setUC(char UC) { write_eeprom(0x0003, UC); } void setSensorUC(char SensorUC) { write_eeprom(0x0004, SensorUC); } char getSensorUC(void) { return read_eeprom(0x04); } void setSensorCommand(char SensorCommand) { write_eeprom(0x0005, SensorCommand); } char getSensorCommand(void) { return read_eeprom(0x05); }

TDI - Transdutores domóticos inteligentes

Relatório Final 142/276

Código principal – interface.c #include "interface.h" #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #include "misc.h" #include "D:\Domotica\PIC Programming\x10func.h" char a; void X10Transmit(); void StartPWM(void); void X10Receive(int1 RxBit); void X10TermTx(void); #int_EXT EXT_isr() { #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm INTEDG ^=1; TCounter500ms++; if (TCounter500ms > 50) // 500 ms { TCounter1s++; TCounter500ms = 0; TUpdate = 1; } if (TCounter1s > 60) // 500 ms { if (SBWait == 1) TCounter1min++; TCounter1s = 0; }

TDI - Transdutores domóticos inteligentes

Relatório Final 143/276

if (TCounter1min > 1) // 500 ms { SBWait = 2; TCounter1min = 0; } // Transmissão if ( (TxBusy == 1) && (w8hc > 8) ) { X10Transmit(); } // Recepção else { set_timer0(0xE2); T0IF = 0; enable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } #int_RTCC RTCC_isr() { int i; #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5

TDI - Transdutores domóticos inteligentes

Relatório Final 144/276

BCF status,6 MOVWF save_status #endasm if ((TxBusy == 1) && (w8hc > 8) ) { // Activa a PWM para as outras fases if ((TxStopPWM == 0) && (TxPhase >= 1)) StartPWM(); else { TxStopPWM = 0; setup_ccp1(CCP_OFF); disable_interrupts(INT_RTCC); if (TxPhase < 3) { set_timer0(0xBC); T0IF = 0; enable_interrupts(INT_RTCC); } if (TxPhase >= 3) TxPhase = 0; } } // Recepcao else { if (X10IN == 0) { X10Receive(X10IN); if (w8hc <= 8) w8hc++; } else { w8hc = 0; X10Receive(X10IN); } if (RSdataToSend == 1) { RSdataToSend = 0; i=0; do { putc(RSTxCommand[i]);

TDI - Transdutores domóticos inteligentes

Relatório Final 145/276

i++; } while (RSTxCommand[i-1] != 23); } disable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } void X10TermTx(void) { TxBuffer1 = 0; TxBuffer2 = 0; TxBusy = 0; TxCount = 0; TxState = 0; TxExtCode = 0; TxSpcCode = 0; } void StartPWM(void) { setup_ccp1(CCP_PWM); set_timer0(0xDF); T0IF = 0; enable_interrupts(INT_RTCC); TxPhase++; TxStopPWM = 1; }

TDI - Transdutores domóticos inteligentes

Relatório Final 146/276

void X10Transmit() { if (TxExtCode == 0) { // Caso do Special Codes, tipo DIM e BRIGHT if ((TxSpcCode == 1) && (TxState == 0)) TxState = 3; if ((TxCount < 22) && (TxState <= 1)) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } // espera o 8 half cycles (TxCount em 255 para impedir ke quando esperou os 8 hc volte a esta condicao // esta a fazer mais devido a estrutura do programa... mas nao faz mal else if ((TxCount != 255) && (TxState == 2)) { w8hc = 0; TxCount = 255; } else if ((TxCount < 22) && ( (TxState >= 3) && (TxState <= 4))) { if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 5) X10TermTx(); // Determina as passagens para o outro estado if ( ((TxCount == 22) && (TxState <= 1)) || ((w8hc > 8) && (TxState == 2)) || ((TxCount == 22) && ((TxState >= 3) && (TxState <= 4)) ) ) { TxState++; TxCount = 0; } } // Codigo Extendido else { if (((TxCount < 30) && (TxState == 0)) || ((TxCount < 30) && (TxState == 2))) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (((TxCount < 32) && (TxState == 1)) || ((TxCount < 32) && (TxState == 3))){ if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 4) X10TermTx();

TDI - Transdutores domóticos inteligentes

Relatório Final 147/276

if ( ((TxCount == 30) && ((TxState == 0) || (TxState == 2))) || ((TxCount == 32) && ((TxState == 1) || (TxState == 3)))) { TxState++; TxCount = 0; } } } void X10Receive(int1 RxBit) { if (RxStartCode != 0x0E) { // 1110 RxStartCode = RxStartCode << 1; if (RxBit == 1) RxStartCode |= 0x01; RxStartCode &= 0x0F; if (RxStartCode == 0x0E) { RxCounter = 0; RxBuffer1 = 0; RxBuffer2 = 0; RxError[0]=0; RxError[1]=0; } } else if (RxStartCode == 0x0E) { if (RxCounter < 8) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 7) { RxError[RxState] += check8(RxBuffer1); RxHC[RxState] = decodeX10(RxBuffer1, 'H'); } }

TDI - Transdutores domóticos inteligentes

Relatório Final 148/276

else if ((RxCounter >=8) && (RxCounter < 16)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 15) { RxError[RxState] += check8(RxBuffer1); } } else if ((RxCounter >=16) && (RxCounter < 18)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 17) { if (RxBuffer2 == 0x01) { RxDC[RxState] = decodeX10(RxBuffer1, 'U'); RxFC[RxState] = 1;} else if (RxBuffer2 == 0x02) { RxDC[RxState] = decodeX10(RxBuffer1, 'D'); RxFC[RxState] = 2; } else RxError[RxState] += 1; if ((RxDC[RxState] == 8) && (RxFC[RxState] == 2)) {} // Caso n seja um extended code else { RxStartCode=0; if (RxState == 1) { RxState = 0; if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 1; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; } } else RxState = 1; } } }

TDI - Transdutores domóticos inteligentes

Relatório Final 149/276

//codigo extendido else if ((RxCounter >=18) && (RxCounter < 26)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 25) { RxError[RxState] += check8(RxBuffer1); RxExtDC[RxState] = decodeX10(RxBuffer1, 'U'); } } else if ((RxCounter >=26) && (RxCounter < 42)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 41) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtData[RxState] = X10decompl(RxBuffer2); } } else if ((RxCounter >=42) && (RxCounter < 58)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 57) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtCommand[RxState] = X10decompl(RxBuffer2); RxStartCode=0; if (RxState == 1) { if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 2; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; RxExtDC[0]=RxExtDC[RxOk]; RxExtData[0] = RxExtData[RxOk]; RxExtCommand[0] = RxExtCommand[RxOk]; }

TDI - Transdutores domóticos inteligentes

Relatório Final 150/276

RxState = 0; } else RxState = 1; } } RxCounter++; } } void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_1(T1_DISABLED); setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL); setup_timer_2(T2_DIV_BY_4, 3, 1); set_pwm1_duty(2); setup_ccp1(CCP_OFF); LED_Z1 = 0; LED_Z2 = 0; LED_Z3 = 0; LED_Z4 = 0; LED_SB = 0; LED_ACTIVE = 0; BUZZER = 0; set_tris_b(0x7F); set_tris_d(0x00); printf("Flood Module\r\n"); SetUC(15);

TDI - Transdutores domóticos inteligentes

Relatório Final 151/276

SetHC('B'); SetModuleId(0x1004); ModuleHC = getHC(); ModuleUC = getUC(); ModuleEnable = 0; last_state = BUTTON; // Inicialização de variaveis INTEDG = 0; w8hc = 0; TxBusy = 0; TxState = 0; TxPhase = 0; TxStopPWM = 0; RxComplete = 0; RxStartCode = 0; RxState = 0; SerialNConfig = 0; TCounter500ms = 0; TCounter1min = 0; TCounter1s = 0; TUpdate = 0; SBWait = 0; // Estado inicial da central LED_ACTIVE = 1; ZoneState = 0; SystemActive = 1; SystemAlarm = 0; sentCommand = 0; disable_interrupts(INT_RTCC); enable_interrupts(INT_EXT); enable_interrupts(global); while(TRUE) { if (RxComplete == 1) { RxComplete = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 152/276

disable_interrupts(INT_EXT); printf("%d HC %c ",RxExtended, RxHC[0]); if (RxExtended == 1) { printf("UC/DC %d (%d) \n\r", RxDC[0], RxFC[0]); } else { printf("%d ", RxExtDC[0]); printf("%d ", RxExtData[0]); printf("%d ", RxExtCommand[0]); } enable_interrupts(INT_EXT); if (RxExtended == 1) { if ((RxFC[0] == 1) && (RxHC[0] == ModuleHC) && (RxDC[0] == ModuleUC)) ModuleEnable = 1; else if (RxFC[0] == 1) ModuleEnable = 0; } else if (RxExtended == 2) { if ( (RxExtCommand[0] == 0x61) && (RxExtData[0] == (getModuleId() & 0xFF)) ) SerialNConfig++; else if ( (RxExtCommand[0] == 0x62) && (RxExtData[0] == ((getModuleId() >> 8) & 0xFF)) ) SerialNConfig++; else SerialNConfig=0; if ((RxHC[0] == ModuleHC) && (RxExtDC[0] == ModuleUC)) ModuleEnable = 1; } //Altera HC e UC via serial Number if (SerialNConfig == 2) { SerialNConfig = 0; setHC(RxHC[0]); setUC(RxExtDC[0]); ModuleHC = getHC(); ModuleUC = getUC(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } else if ((RxExtended == 2) && (ModuleEnable == 1)) { // Change HC e UC if (RxExtCommand[0] == 0x63) {

TDI - Transdutores domóticos inteligentes

Relatório Final 153/276

setHC(((RxExtData[0] >> 4) & 0x0F) + 65); setUC((RxExtData[0] & 0x0F) + 1); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma ModuleHC = getHC(); ModuleUC = getUC(); } //Change Sensor settings if (RxExtCommand[0] == 0x64) { setSensorUC((RxExtData[0] >> 3) & 0x1F); setSensorCommand(RxExtData[0] & 0x07); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma // printf("%d %d", getSensorUC(), getSensorCommand()); } } else if ((RxHC[0] == ModuleHC) && (RxFC[0] == 2) && (ModuleEnable == 1)) { switch (RxDC[0]) { case 9 : { // Hail Request sendX10(0, 0, ModuleHC, ModuleUC, 10, 0, 0); //HAIL ACK break; } case 16 : { // Status Request if (SystemAlarm == 1) sendX10(0, 0, ModuleHC, ModuleUC, 14, 0, 0); // Status ON else sendX10(0, 0, ModuleHC, ModuleUC, 15, 0, 0); // Status OFF break; } default : break; } } } if (TxBusy == 0) { if (SystemActive == 1) { ZoneState = 0; if (SENSOR_Z1 == 0) if (SENSOR_Z1 == 0) ZoneState = 0x01; if (SENSOR_Z2 == 0) if (SENSOR_Z2 == 0) ZoneState+= 0x02 & 0x0F;

TDI - Transdutores domóticos inteligentes

Relatório Final 154/276

if (SENSOR_Z3 == 0) if (SENSOR_Z3 == 0) ZoneState+= 0x04 & 0x0F; if (SENSOR_Z4 == 0) if (SENSOR_Z4 == 0) ZoneState+= 0x08 & 0x0F; if (ZoneState != 0x00) { SystemAlarm = 1; if (ZoneState == (0x01 & 0x01)) LED_Z1 = 1; if (ZoneState == (0x02 & 0x02)) LED_Z2 = 1; if (ZoneState == (0x04 & 0x04)) LED_Z3 = 1; if (ZoneState == (0x08 & 0x08)) LED_Z4 = 1; BUZZER = 1; } } if ((SBWait == 2) && (SystemActive == 0)) { SBWait = 0; SystemActive = 1; LED_SB = 0; LED_ACTIVE = 1; } if ((BUTTON == 0) && (last_state!=BUTTON) && (TUpdate == 1)) { last_state = 0; TUpdate = 0; // Caso Sistema com alarme activo if (SystemAlarm == 1) { SystemAlarm = 0; SystemActive = 0; LED_SB = 1; LED_ACTIVE = 0; BUZZER = 0; LED_Z1 = 0; LED_Z2 = 0; LED_Z3 = 0; LED_Z4 = 0; } //Caso sistema activo sem alarme else if (SystemActive == 1) { SystemActive = 0; LED_SB = 1;

TDI - Transdutores domóticos inteligentes

Relatório Final 155/276

LED_ACTIVE = 0; SBWait = 1; } //Caso Sistema em stand by else if (SystemActive == 0) { SystemActive = 1; LED_SB = 0; LED_ACTIVE = 1; sentCommand = 0; } } if (BUTTON == 1) last_state = 1; if ((sentCommand == 0) && (SystemAlarm == 1)) { if (sentCommand == 0) { // putc('x'); sentCommand = 1; sendX10(0, 0, ModuleHC, getSensorUC(), getSensorCommand(), 0, 0); } } if (kbhit()) { RSBuffer = getc(); if (RSBuffer == 'o') { disable_interrupts(INT_EXT); printf("S1 %d S2 %d S3 %d S4 %d\n\r", SENSOR_Z1, SENSOR_Z2, SENSOR_Z3, SENSOR_Z4); enable_interrupts(INT_EXT); } else if (RSBuffer == 'p') { sendX10(0, 0, 'A', 1, 1, 0, 0); } else if (RSBuffer == 'q') { disable_interrupts(INT_EXT); printf("%c%d", GetHC(), GetUC()); enable_interrupts(INT_EXT);

TDI - Transdutores domóticos inteligentes

Relatório Final 156/276

} else if (RSBuffer == 'a') BUZZER = 1; else if (RSBuffer == 's') BUZZER = 0; else if (RSBuffer == '1') LED_Z1 = 0; else if (RSBuffer == '5') LED_Z1 = 1; else if (RSBuffer == '2') LED_Z2 = 0; else if (RSBuffer == '6') LED_Z2 = 1; else if (RSBuffer == '3') LED_Z3 = 0; else if (RSBuffer == '7') LED_Z3 = 1; else if (RSBuffer == '4') LED_Z4 = 0; else if (RSBuffer == '8') LED_Z4 = 1; else if (RSBuffer == 'z') LED_ACTIVE = 0; else if (RSBuffer == 'x') LED_ACTIVE = 1; else if (RSBuffer == 'c') LED_SB = 0; else if (RSBuffer == 'v') LED_SB = 1; } } } } Código fonte do modulo “Actuador AC” Livraria misc.h // Acesso directo aos registos #bit T0IF = 0x0b.2 #bit X10IN = 0x06.1 #bit INTEDG = 0x81.6 #bit LED_ON = 0x07.0 #bit LED_OFF = 0x07.1 #bit BUTTON_ON = 0x06.2 #bit BUTTON_OFF = 0x06.3

TDI - Transdutores domóticos inteligentes

Relatório Final 157/276

#bit ACT_CTRL = 0x07.3 #bit RTCAS = 0x06.4 // PORTA B.4 #bit RTCWR = 0x06.5 // PORTA B.5 #bit RTCRD = 0x06.6 // PORTA B.6 #byte RTCAD = 0x08 // PORTA D int save_w; #locate save_w=0x7f int save_status; #locate save_status=0x20 #byte status = 3 int const BufferSize = 13; int const MaxSched = 31; char ModuleHC, ModuleUC; int1 ModuleEnable; // Transmissão int32 TxBuffer1, TxBuffer2; int1 TxExtCode, TxSpcCode; int TxCount; int1 TxBusy; char TxState; // 0 - Primeiro HC UC // 1 - Segundo HC UC // 2 - Wait 4 cycles // 3 - Primeiro HC AC // 4 - Segundo HC AC // 5 - End char TxPhase; int1 TxStopPWM; char W8hc; // wait 8 half cycles // Recepção char RxStartCode; char RxBuffer1; int16 RxBuffer2; char RxError[2]; char RxHC[2]; char RxDC[2]; char RxFC[2];

TDI - Transdutores domóticos inteligentes

Relatório Final 158/276

char RxExtDC[2]; char RxExtData[2]; char RxExtCommand[2]; char RxState; char RxExtended; char RxCounter; char RxOk; char RxComplete; /* // Porta Serie int1 RSdataRec; int1 RSdataToSend; char RScount; char RSRxcommand[BufferSize]; char RSTxcommand[BufferSize]; */ //Agendamento int1 X10RCVsetClock; int1 X10RCVsetSched; char X10RCVOption, X10RCVCommand, X10RCVHour, X10RCVMin, X10RCVSec; char X10RCVMonth, X10RCVYear, X10RCVDoM, X10RCVDoW; char X10RCVcount; char RSbuffer; char SerialNConfig; // Timer (RTC) char RTCHour, RTCMin, RTCSec, RTCDofW, RTCDofM, RTCMonth, RTCYear; char RTCOldMin; // Guarda o estado da ultima verificação char RTCCount; // Contador para os 250 ms (aproximadamente 10ms * 25 - 10 ms e' o tempo que ocorre a interupcao) char RTCUpdate; //Flag para efectuar o update do RTC char SchedCommand; void printbin(char c) { int i; i = 7;

TDI - Transdutores domóticos inteligentes

Relatório Final 159/276

while (i!=-1) { if (((c >> i) & 0x01) == 1) putc('1'); else putc('0'); i--; } } printEeprom(int offset) { int i,j; for (i=0; i<=offset; i=i+8) { printf("%x\t :", i); for (j=0; j<=7; j++) printf(" %x", read_eeprom(i+j)); printf("\r\n"); if (i == 0xA0) {printf("---- More ----\r\n"); getc();} if (i==0xF8) break; } } int16 getModuleId(void) { return ((int16)read_eeprom(0x00) << 8) + read_eeprom(0x01); } void SetModuleId(int16 value) { write_eeprom(0x0000, (int) (value >> 8)); write_eeprom(0x0001, (int) value); } char getHC(void) { return read_eeprom(0x02); } char getUC(void) { return read_eeprom(0x03); } void setHC(char HC) { write_eeprom(0x0002, HC); }

TDI - Transdutores domóticos inteligentes

Relatório Final 160/276

void setUC(char UC) { write_eeprom(0x0003, UC); } // Busca a proxima posicao livre para agendar uma tarefa (se 0 nao ha espaco para agendamento) char scheduleFreePos(void) { char i; char freepos; freepos = 0; for ( i=4; i <(8 * MaxSched + 4); i= i +8) { if (read_eeprom(i) == 0xFF) { freepos = i; break; } if (i == 252) break; } return freepos; } // Cria um agendamento int1 setSchedule(char id, char Hour, char Min, char DoM, char DoW, char Month, char Year, char Command) { int schPos; schPos = ScheduleFreePos(); if (schPos == 0) return 0; else { write_eeprom(SchPos, id); write_eeprom(SchPos + 1, Hour); write_eeprom(SchPos + 2, Min); write_eeprom(SchPos + 3, DoM); write_eeprom(SchPos + 4, DoW); write_eeprom(SchPos + 5, Month); write_eeprom(SchPos + 6, Year); write_eeprom(SchPos + 7, Command); return 1; } }

TDI - Transdutores domóticos inteligentes

Relatório Final 161/276

// Apaga todos os agendamentos void scheduleClear(void) { char i; for ( i=4; i <=254; i++) { write_eeprom(i,0xFF); } } // Verifica se ha algum agendamento a executar e retorna o comando a executar (0 nao encontrou ocorrencias) char checkSchedules(void) { int i; char schOption; schOption = 0xFF; for ( i=4; i <=(8 * MaxSched + 4); i=i+8) { schOption = read_eeprom(i); if (schOption != 0xFF) { // Todos as horas if (schOption == 0x01) { if (RTCMin == read_eeprom(i+2)) return read_eeprom(i+7); } // Todos os dias else if (schOption == 0x02) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1))) return read_eeprom(i+7); } // Todas as semanas else if (schOption == 0x03) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofW == read_eeprom(i+4))) return read_eeprom(i+7); } // Todas os meses else if (schOption == 0x04) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1))

TDI - Transdutores domóticos inteligentes

Relatório Final 162/276

&& (RTCDofM == read_eeprom(i+3))) return read_eeprom(i+7); } // Todas os anos else if (schOption == 0x05) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofM == read_eeprom(i+3)) && (RTCMonth == read_eeprom(i+5))) return read_eeprom(i+7); } // Unica vez else if (schOption == 0x06) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofM == read_eeprom(i+3)) && (RTCMonth == read_eeprom(i+5)) && (RTCYear == read_eeprom(i+6))) return read_eeprom(i+7); } } if (i == 252) return 0x00; } return 0x00; } Livraria rtc.h char RTCRead(char addr) { char value; set_tris_d(0x00); value = 0; RTCAS = 1; RTCAD = addr; RTCAS = 0; RTCAD = 0x00; set_tris_d(0xFF); RTCRD = 0; delay_cycles(1); value = RTCAD; RTCRD = 1; set_tris_d(0x00); return value; }

TDI - Transdutores domóticos inteligentes

Relatório Final 163/276

void RTCWrite(char addr, char value) { RTCAS = 1; RTCAD = addr; RTCAS = 0; RTCAD = 0x00; RTCWR = 0; delay_cycles(1); RTCAD = value; RTCWR = 1; } void RTCUpdateTime() { RTCMin = RTCRead(0x02); RTCHour = RTCRead(0x04); RTCDofW = RTCRead(0x06); RTCDofM = RTCRead(0x07); RTCMonth = RTCRead(0x08); } void RTCGetCompleteTime() { RTCSec = RtcRead(0x00); RTCMin = RtcRead(0x02); RTCHour = RtcRead(0x04); RTCDofW = RtcRead(0x06); RTCDofM = RtcRead(0x07); RTCMonth = RtcRead(0x08); RTCYear = RtcRead(0x09); } void RTCSetTimeDate(char NewSec, char NewMin, char NewHour, char NewDofW, char NewDofM, char NewMonth, char NewYear) { RTCWrite(0x0B, 0x86); // Activa o SETUP MODE RTCWrite(0x00, NewSec); // Segundos RTCWrite(0x02, NewMin); // Minutos RTCWrite(0x04, NewHour); // Horas RTCWrite(0x06, NewDofW); // Dia da Semana RTCWrite(0x07, NewDofM); // Dia do Mes RTCWrite(0x08, NewMonth); // Mes RTCWrite(0x09, NewYear); // Ano RTCWrite(0x32, 0x14); // Century Bit (ano 20xx) RTCWrite(0x0B, 0x06); // Inactiva o SETUP MODE }

TDI - Transdutores domóticos inteligentes

Relatório Final 164/276

void RTCEnable() { RTCWrite(0x0A, 0x21); // Activa o RTC } void RTCDisable() { RTCWrite(0x0A, 0x00); // Inactiva o RTC } void RTCinit() { RTCAS = 0; RTCWR = 1; RTCRD = 1; } Código principal – interface.c #include "interface.h" #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #include "misc.h" #include "D:\Domotica\PIC Programming\x10func.h" #include "rtc.h" void X10Transmit(); void StartPWM(void); void X10Receive(int1 RxBit); void X10TermTx(void); #int_EXT EXT_isr() { #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm

TDI - Transdutores domóticos inteligentes

Relatório Final 165/276

INTEDG ^=1; // Transmissão if ( (TxBusy == 1) && (w8hc > 8) ) { X10Transmit(); } // Recepção else { set_timer0(0xE2); T0IF = 0; enable_interrupts(INT_RTCC); } RTCCount++; if (RTCCount > 25) { RTCCount = 0; RTCUpdate = 1; } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } #int_RTCC RTCC_isr() { int i; #asm //store current state of processor MOVWF save_w

TDI - Transdutores domóticos inteligentes

Relatório Final 166/276

SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm if ((TxBusy == 1) && (w8hc > 8) ) { // Activa a PWM para as outras fases if ((TxStopPWM == 0) && (TxPhase >= 1)) StartPWM(); else { TxStopPWM = 0; setup_ccp1(CCP_OFF); disable_interrupts(INT_RTCC); if (TxPhase < 3) { set_timer0(0xBC); T0IF = 0; enable_interrupts(INT_RTCC); } if (TxPhase >= 3) TxPhase = 0; } } // Recepcao else { if (X10IN == 0) { X10Receive(X10IN); if (w8hc <= 8) w8hc++; } else { w8hc = 0; X10Receive(X10IN); } disable_interrupts(INT_RTCC); }

TDI - Transdutores domóticos inteligentes

Relatório Final 167/276

#asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } void X10TermTx(void) { TxBuffer1 = 0; TxBuffer2 = 0; TxBusy = 0; TxCount = 0; TxState = 0; TxExtCode = 0; TxSpcCode = 0; } void StartPWM(void) { setup_ccp1(CCP_PWM); set_timer0(0xDF); T0IF = 0; enable_interrupts(INT_RTCC); TxPhase++; TxStopPWM = 1; } void X10Transmit() { if (TxExtCode == 0) { // Caso do Special Codes, tipo DIM e BRIGHT if ((TxSpcCode == 1) && (TxState == 0)) TxState = 3;

TDI - Transdutores domóticos inteligentes

Relatório Final 168/276

if ((TxCount < 22) && (TxState <= 1)) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } // espera o 8 half cycles (TxCount em 255 para impedir ke quando esperou os 8 hc volte a esta condicao // esta a fazer mais devido a estrutura do programa... mas nao faz mal else if ((TxCount != 255) && (TxState == 2)) { w8hc = 0; TxCount = 255; } else if ((TxCount < 22) && ( (TxState >= 3) && (TxState <= 4))) { if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 5) X10TermTx(); // Determina as passagens para o outro estado if ( ((TxCount == 22) && (TxState <= 1)) || ((w8hc > 8) && (TxState == 2)) || ((TxCount == 22) && ((TxState >= 3) && (TxState <= 4)) ) ) { TxState++; TxCount = 0; } } // Codigo Extendido else { if (((TxCount < 30) && (TxState == 0)) || ((TxCount < 30) && (TxState == 2))) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (((TxCount < 32) && (TxState == 1)) || ((TxCount < 32) && (TxState == 3))){ if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 4) X10TermTx(); if ( ((TxCount == 30) && ((TxState == 0) || (TxState == 2))) || ((TxCount == 32) && ((TxState == 1) || (TxState == 3)))) { TxState++; TxCount = 0; }

TDI - Transdutores domóticos inteligentes

Relatório Final 169/276

} } void X10Receive(int1 RxBit) { if (RxStartCode != 0x0E) { // 1110 RxStartCode = RxStartCode << 1; if (RxBit == 1) RxStartCode |= 0x01; RxStartCode &= 0x0F; if (RxStartCode == 0x0E) { RxCounter = 0; RxBuffer1 = 0; RxBuffer2 = 0; RxError[0]=0; RxError[1]=0; } } else if (RxStartCode == 0x0E) { if (RxCounter < 8) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 7) { RxError[RxState] += check8(RxBuffer1); RxHC[RxState] = decodeX10(RxBuffer1, 'H'); } } else if ((RxCounter >=8) && (RxCounter < 16)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 15) { RxError[RxState] += check8(RxBuffer1); } }

TDI - Transdutores domóticos inteligentes

Relatório Final 170/276

else if ((RxCounter >=16) && (RxCounter < 18)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 17) { if (RxBuffer2 == 0x01) { RxDC[RxState] = decodeX10(RxBuffer1, 'U'); RxFC[RxState] = 1;} else if (RxBuffer2 == 0x02) { RxDC[RxState] = decodeX10(RxBuffer1, 'D'); RxFC[RxState] = 2; } else RxError[RxState] += 1; if ((RxDC[RxState] == 8) && (RxFC[RxState] == 2)) {} // Caso n seja um extended code else { RxStartCode=0; if (RxState == 1) { RxState = 0; if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 1; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; } } else RxState = 1; } } } //codigo extendido else if ((RxCounter >=18) && (RxCounter < 26)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01;

TDI - Transdutores domóticos inteligentes

Relatório Final 171/276

if (RxCounter == 25) { RxError[RxState] += check8(RxBuffer1); RxExtDC[RxState] = decodeX10(RxBuffer1, 'U'); } } else if ((RxCounter >=26) && (RxCounter < 42)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 41) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtData[RxState] = X10decompl(RxBuffer2); } } else if ((RxCounter >=42) && (RxCounter < 58)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 57) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtCommand[RxState] = X10decompl(RxBuffer2); RxStartCode=0; if (RxState == 1) { if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 2; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; RxExtDC[0]=RxExtDC[RxOk]; RxExtData[0] = RxExtData[RxOk]; RxExtCommand[0] = RxExtCommand[RxOk]; } RxState = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 172/276

} else RxState = 1; } } RxCounter++; } } void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_1(T1_DISABLED); setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL); setup_timer_2(T2_DIV_BY_4, 3, 1); set_pwm1_duty(2); setup_ccp1(CCP_OFF); set_tris_b(0x0F); set_tris_d(0x00); set_tris_c(0x80); //1000 0000 printf("AC Module\r\n"); SetModuleId(1001); ModuleHC = getHC(); ModuleUC = getUC();

TDI - Transdutores domóticos inteligentes

Relatório Final 173/276

ModuleEnable = 0; // Inicialização de variaveis INTEDG = 0; w8hc = 0; TxBusy = 0; TxState = 0; TxPhase = 0; TxStopPWM = 0; RxComplete = 0; RxStartCode = 0; RxState = 0; LED_ON = 0; LED_OFF = 1; ACT_CTRL = 1; RTCCount = 0; RTCUpdate = 0; RTCOldMin = 255; X10RCVsetClock = 0; X10RCVsetSched = 0; RTCInit(); disable_interrupts(INT_RTCC); enable_interrupts(INT_EXT); enable_interrupts(global); while(TRUE) { if (RxComplete == 1) { RxComplete = 0; disable_interrupts(INT_EXT); printf("%d HC %c ",RxExtended, RxHC[0]);

TDI - Transdutores domóticos inteligentes

Relatório Final 174/276

if (RxExtended == 1) { printf("UC/DC %d (%d)\n\r", RxDC[0], RxFC[0]); } else { printf("%d ", RxExtDC[0]); printf("%d ", RxExtData[0]); printf("%d ", RxExtCommand[0]); } enable_interrupts(INT_EXT); if (RxExtended == 1) { if ((RxFC[0] == 1) && (RxHC[0] == ModuleHC) && (RxDC[0] == ModuleUC)) ModuleEnable = 1; else if (RxFC[0] == 1) ModuleEnable = 0; } else if (RxExtended == 2) { if ( (RxExtCommand[0] == 0x61) && (RxExtData[0] == (getModuleId() & 0xFF)) ) SerialNConfig++; else if ( (RxExtCommand[0] == 0x62) && (RxExtData[0] == ((getModuleId() >> 8) & 0xFF)) ) SerialNConfig++; else SerialNConfig=0; if ((RxHC[0] == ModuleHC) && (RxExtDC[0] == ModuleUC)) ModuleEnable = 1; } //Altera HC e UC via serial Number if (SerialNConfig == 2) { SerialNConfig = 0; setHC(RxHC[0]); setUC(RxExtDC[0]); ModuleHC = getHC(); ModuleUC = getUC(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } else if ((RxExtended == 2) && (ModuleEnable == 1)) { // Change HC e UC if (RxExtCommand[0] == 0x63) { setHC(((RxExtData[0] >> 4) & 0x0F) + 65); setUC((RxExtData[0] & 0x0F) + 1); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma ModuleHC = getHC(); ModuleUC = getUC(); }

TDI - Transdutores domóticos inteligentes

Relatório Final 175/276

//Set Schedules if (RxExtCommand[0] == 0x65) { X10RCVOption = (RxExtData[0] >> 4) & 0x0F; X10RCVCommand = RxExtData[0] & 0x0F; if (X10RCVOption == 0x0F) { putc('C'); ScheduleClear(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } X10RCVsetSched = 1; X10RCVCount = 0; X10RCVOption = 0; X10RCVCommand = 0; X10RCVHour = 0; X10RCVMin = 0; X10RCVMonth = 0; X10RCVYear = 0; X10RCVDoM = 0; X10RCVDoW = 0; } //Set RTC if (RxExtCommand[0] == 0x66) { X10RCVsetClock = 1; X10RCVCount = 0; } //Ano if (RxExtCommand[0] == 0x6B) { X10RCVYear = RxExtData[0]; X10RCVCount ++; } //Mes if (RxExtCommand[0] == 0x6A) { X10RCVMonth = RxExtData[0]; X10RCVCount ++; } //Dia do Mes if (RxExtCommand[0] == 0x6C) { X10RCVDoM = RxExtData[0]; X10RCVCount ++; } //Dia da Semana if (RxExtCommand[0] == 0x6D) { X10RCVDoW = RxExtData[0]; X10RCVCount ++;

TDI - Transdutores domóticos inteligentes

Relatório Final 176/276

} //Hora if (RxExtCommand[0] == 0x67) { X10RCVHour = RxExtData[0]; X10RCVCount ++; } //Min if (RxExtCommand[0] == 0x68) { X10RCVMin = RxExtData[0]; X10RCVCount ++; } //Sec if (RxExtCommand[0] == 0x69) { X10RCVSec = RxExtData[0]; X10RCVCount ++; } //End if (RxExtCommand[0] == 0x6F) { if (X10RCVsetClock == 1) { if (X10RCVCount == 7) { printf("acerta relogio"); RTCSetTimeDate(X10RCVSec, X10RCVMin, X10RCVHour, X10RCVDoW, X10RCVDoM, X10RCVMonth, X10RCVYear); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } } if (X10RCVsetSched == 1) { if (((X10RCVOption == 1) && (X10RCVOption == 1)) || ((X10RCVOption == 2) && (X10RCVOption == 2)) || ((X10RCVOption == 3) && (X10RCVOption == 3)) || ((X10RCVOption == 4) && (X10RCVOption == 3)) || ((X10RCVOption == 5) && (X10RCVOption == 4)) || ((X10RCVOption == 2) && (X10RCVOption == 5))) setSchedule(X10RCVOption, X10RCVHour, X10RCVMin, X10RCVDoM, X10RCVDoW, X10RCVMonth, X10RCVYear, X10RCVCommand); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } X10RCVsetSched = 0; X10RCVsetClock = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 177/276

X10RCVCount = 0; } } else if ((RxHC[0] == ModuleHC) && (RxFC[0] == 2) && (ModuleEnable == 1)) { if ((RxDC[0] == 1) || (RxDC[0] == 5)) {// ON e ALL LIGHTS ON ACT_CTRL = 0; LED_OFF = 0; LED_ON = 1; } else if ((RxDC[0] == 2) || (RxDC[0] == 6) || (RxDC[0] == 7)) { // OFF, ALL UNITS OFF e ALL LIGHTS OFF ACT_CTRL = 1; LED_OFF = 1; LED_ON = 0; } else if (RxDC[0] == 9) { // Hail Request sendX10(0, 0, ModuleHC, ModuleUC, 10, 0, 0); //HAIL ACK } else if (RxDC[0] == 16) { // Status request if (ACT_CTRL == 0) sendX10(0, 0, ModuleHC, ModuleUC, 14, 0, 0); // Status ON else sendX10(0, 0, ModuleHC, ModuleUC, 15, 0, 0); // Status OFF } } } if (TxBusy == 0) { if (RTCUpdate == 1) { RTCUpdate = 0; RTCUpdateTime(); if (RTCOldMin != RTCMin) { RTCOldMin = RTCMin; SchedCommand = checkSchedules();

TDI - Transdutores domóticos inteligentes

Relatório Final 178/276

if (SchedCommand == 1) { ACT_CTRL = 0; LED_OFF = 0; LED_ON = 1; } else if (SchedCommand == 2) { ACT_CTRL = 1; LED_OFF = 1; LED_ON = 0; } } } if (BUTTON_ON == 0) { ACT_CTRL = 0; LED_ON = 1; LED_OFF = 0; } else if (BUTTON_OFF == 0) { ACT_CTRL = 1; LED_OFF = 1; LED_ON = 0; } if (kbhit()) { RSBuffer = getc(); if (RSBuffer == '1') { disable_interrupts(INT_EXT); printEeprom(0xFF); enable_interrupts(INT_EXT); } else if (RSBuffer == '2') { disable_interrupts(INT_EXT); RTCGetCompleteTime(); printf("\r\n%U:%U:%U %U / %U / %U Dia da Semana %U\r\n", RTCHour, RTCMin, RTCSec, RTCDofM, RTCMonth, RTCYear, RTCDofW); enable_interrupts(INT_EXT); }

TDI - Transdutores domóticos inteligentes

Relatório Final 179/276

else if (RSBuffer == '3') { disable_interrupts(INT_EXT); printf("\r\nHC - %c UC - %d\r\n", GetHC(), GetUC()); enable_interrupts(INT_EXT); } } } } } Código fonte do modulo “Actuador DC” Livraria misc.h // Acesso directo aos registos #bit T0IF = 0x0b.2 #bit X10IN = 0x06.1 #bit INTEDG = 0x81.6 #bit LED_ON = 0x07.0 #bit LED_OFF = 0x07.1 #bit BUTTON_ON = 0x06.2 #bit BUTTON_OFF = 0x06.3 #bit ACT_CTRL = 0x07.3 #bit RTCAS = 0x06.4 // PORTA B.4 #bit RTCWR = 0x06.5 // PORTA B.5 #bit RTCRD = 0x06.6 // PORTA B.6 #byte RTCAD = 0x08 // PORTA D int save_w; #locate save_w=0x7f int save_status; #locate save_status=0x20 #byte status = 3 int const BufferSize = 13; int const MaxSched = 31;

TDI - Transdutores domóticos inteligentes

Relatório Final 180/276

char ModuleHC, ModuleUC; int1 ModuleEnable; // Transmissão int32 TxBuffer1, TxBuffer2; int1 TxExtCode, TxSpcCode; int TxCount; int1 TxBusy; char TxState; // 0 - Primeiro HC UC // 1 - Segundo HC UC // 2 - Wait 4 cycles // 3 - Primeiro HC AC // 4 - Segundo HC AC // 5 - End char TxPhase; int1 TxStopPWM; char W8hc; // wait 8 half cycles // Recepção char RxStartCode; char RxBuffer1; int16 RxBuffer2; char RxError[2]; char RxHC[2]; char RxDC[2]; char RxFC[2]; char RxExtDC[2]; char RxExtData[2]; char RxExtCommand[2]; char RxState; char RxExtended; char RxCounter; char RxOk; char RxComplete; /* // Porta Serie int1 RSdataRec; int1 RSdataToSend; char RScount; char RSRxcommand[BufferSize]; char RSTxcommand[BufferSize]; */

TDI - Transdutores domóticos inteligentes

Relatório Final 181/276

//Agendamento int1 X10RCVsetClock; int1 X10RCVsetSched; char X10RCVOption, X10RCVCommand, X10RCVHour, X10RCVMin, X10RCVSec; char X10RCVMonth, X10RCVYear, X10RCVDoM, X10RCVDoW; char X10RCVcount; char RSbuffer; char SerialNConfig; // Timer (RTC) char RTCHour, RTCMin, RTCSec, RTCDofW, RTCDofM, RTCMonth, RTCYear; char RTCOldMin; // Guarda o estado da ultima verificação char RTCCount; // Contador para os 250 ms (aproximadamente 10ms * 25 - 10 ms e' o tempo que ocorre a interupcao) char RTCUpdate; //Flag para efectuar o update do RTC char SchedCommand; void printbin(char c) { int i; i = 7; while (i!=-1) { if (((c >> i) & 0x01) == 1) putc('1'); else putc('0'); i--; } } printEeprom(int offset) { int i,j; for (i=0; i<=offset; i=i+8) { printf("%x\t :", i); for (j=0; j<=7; j++) printf(" %x", read_eeprom(i+j)); printf("\r\n");

TDI - Transdutores domóticos inteligentes

Relatório Final 182/276

if (i == 0xA0) {printf("---- More ----\r\n"); getc();} if (i==0xF8) break; } } int16 getModuleId(void) { return ((int16)read_eeprom(0x00) << 8) + read_eeprom(0x01); } void SetModuleId(int16 value) { write_eeprom(0x0000, (int) (value >> 8)); write_eeprom(0x0001, (int) value); } char getHC(void) { return read_eeprom(0x02); } char getUC(void) { return read_eeprom(0x03); } void setHC(char HC) { write_eeprom(0x0002, HC); } void setUC(char UC) { write_eeprom(0x0003, UC); } // Busca a proxima posicao livre para agendar uma tarefa (se 0 nao ha espaco para agendamento) char scheduleFreePos(void) { char i; char freepos; freepos = 0; for ( i=4; i <(8 * MaxSched + 4); i= i +8) {

TDI - Transdutores domóticos inteligentes

Relatório Final 183/276

if (read_eeprom(i) == 0xFF) { freepos = i; break; } if (i == 252) break; } return freepos; } // Cria um agendamento int1 setSchedule(char id, char Hour, char Min, char DoM, char DoW, char Month, char Year, char Command) { int schPos; schPos = ScheduleFreePos(); if (schPos == 0) return 0; else { write_eeprom(SchPos, id); write_eeprom(SchPos + 1, Hour); write_eeprom(SchPos + 2, Min); write_eeprom(SchPos + 3, DoM); write_eeprom(SchPos + 4, DoW); write_eeprom(SchPos + 5, Month); write_eeprom(SchPos + 6, Year); write_eeprom(SchPos + 7, Command); return 1; } } // Apaga todos os agendamentos void scheduleClear(void) { char i; for ( i=4; i <=254; i++) { write_eeprom(i,0xFF); } } // Verifica se ha algum agendamento a executar e retorna o comando a executar (0 nao encontrou ocorrencias) char checkSchedules(void) { int i;

TDI - Transdutores domóticos inteligentes

Relatório Final 184/276

char schOption; schOption = 0xFF; for ( i=4; i <=(8 * MaxSched + 4); i=i+8) { schOption = read_eeprom(i); if (schOption != 0xFF) { // Todos as horas if (schOption == 0x01) { if (RTCMin == read_eeprom(i+2)) return read_eeprom(i+7); } // Todos os dias else if (schOption == 0x02) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1))) return read_eeprom(i+7); } // Todas as semanas else if (schOption == 0x03) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofW == read_eeprom(i+4))) return read_eeprom(i+7); } // Todas os meses else if (schOption == 0x04) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofM == read_eeprom(i+3))) return read_eeprom(i+7); } // Todas os anos else if (schOption == 0x05) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofM == read_eeprom(i+3)) && (RTCMonth == read_eeprom(i+5))) return read_eeprom(i+7); } // Unica vez else if (schOption == 0x06) { if ((RTCMin == read_eeprom(i+2)) && (RTCHour == read_eeprom(i+1)) && (RTCDofM == read_eeprom(i+3)) && (RTCMonth == read_eeprom(i+5)) && (RTCYear == read_eeprom(i+6))) return read_eeprom(i+7); }

TDI - Transdutores domóticos inteligentes

Relatório Final 185/276

} if (i == 252) return 0x00; } return 0x00; } Livraria rtc.h char RTCRead(char addr) { char value; set_tris_d(0x00); value = 0; RTCAS = 1; RTCAD = addr; RTCAS = 0; RTCAD = 0x00; set_tris_d(0xFF); RTCRD = 0; delay_cycles(1); value = RTCAD; RTCRD = 1; set_tris_d(0x00); return value; } void RTCWrite(char addr, char value) { RTCAS = 1; RTCAD = addr; RTCAS = 0; RTCAD = 0x00; RTCWR = 0; delay_cycles(1); RTCAD = value; RTCWR = 1; } void RTCUpdateTime() { RTCMin = RTCRead(0x02); RTCHour = RTCRead(0x04); RTCDofW = RTCRead(0x06); RTCDofM = RTCRead(0x07);

TDI - Transdutores domóticos inteligentes

Relatório Final 186/276

RTCMonth = RTCRead(0x08); } void RTCGetCompleteTime() { RTCSec = RtcRead(0x00); RTCMin = RtcRead(0x02); RTCHour = RtcRead(0x04); RTCDofW = RtcRead(0x06); RTCDofM = RtcRead(0x07); RTCMonth = RtcRead(0x08); RTCYear = RtcRead(0x09); } void RTCSetTimeDate(char NewSec, char NewMin, char NewHour, char NewDofW, char NewDofM, char NewMonth, char NewYear) { RTCWrite(0x0B, 0x86); // Activa o SETUP MODE RTCWrite(0x00, NewSec); // Segundos RTCWrite(0x02, NewMin); // Minutos RTCWrite(0x04, NewHour); // Horas RTCWrite(0x06, NewDofW); // Dia da Semana RTCWrite(0x07, NewDofM); // Dia do Mes RTCWrite(0x08, NewMonth); // Mes RTCWrite(0x09, NewYear); // Ano RTCWrite(0x32, 0x14); // Century Bit (ano 20xx) RTCWrite(0x0B, 0x06); // Inactiva o SETUP MODE } void RTCEnable() { RTCWrite(0x0A, 0x21); // Activa o RTC } void RTCDisable() { RTCWrite(0x0A, 0x00); // Inactiva o RTC } void RTCinit() { RTCAS = 0; RTCWR = 1; RTCRD = 1; }

TDI - Transdutores domóticos inteligentes

Relatório Final 187/276

Código principal – interface.c #include "interface.h" #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #include "misc.h" #include "D:\Domotica\PIC Programming\x10func.h" #include "rtc.h" void X10Transmit(); void StartPWM(void); void X10Receive(int1 RxBit); void X10TermTx(void); #int_EXT EXT_isr() { #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm INTEDG ^=1; // Transmissão if ( (TxBusy == 1) && (w8hc > 8) ) { X10Transmit(); } // Recepção else { set_timer0(0xE2); T0IF = 0; enable_interrupts(INT_RTCC); }

TDI - Transdutores domóticos inteligentes

Relatório Final 188/276

RTCCount++; if (RTCCount > 25) { RTCCount = 0; RTCUpdate = 1; } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } #int_RTCC RTCC_isr() { int i; #asm //store current state of processor MOVWF save_w SWAPF status,W BCF status,5 BCF status,6 MOVWF save_status #endasm if ((TxBusy == 1) && (w8hc > 8) ) { // Activa a PWM para as outras fases if ((TxStopPWM == 0) && (TxPhase >= 1)) StartPWM(); else { TxStopPWM = 0; setup_ccp1(CCP_OFF); disable_interrupts(INT_RTCC);

TDI - Transdutores domóticos inteligentes

Relatório Final 189/276

if (TxPhase < 3) { set_timer0(0xBC); T0IF = 0; enable_interrupts(INT_RTCC); } if (TxPhase >= 3) TxPhase = 0; } } // Recepcao else { if (X10IN == 0) { X10Receive(X10IN); if (w8hc <= 8) w8hc++; } else { w8hc = 0; X10Receive(X10IN); } disable_interrupts(INT_RTCC); } #asm // restore processor and return from interrupt SWAPF save_status,W MOVWF status SWAPF save_w,F SWAPF save_w,W #endasm } void X10TermTx(void) { TxBuffer1 = 0; TxBuffer2 = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 190/276

TxBusy = 0; TxCount = 0; TxState = 0; TxExtCode = 0; TxSpcCode = 0; } void StartPWM(void) { setup_ccp1(CCP_PWM); set_timer0(0xDF); T0IF = 0; enable_interrupts(INT_RTCC); TxPhase++; TxStopPWM = 1; } void X10Transmit() { if (TxExtCode == 0) { // Caso do Special Codes, tipo DIM e BRIGHT if ((TxSpcCode == 1) && (TxState == 0)) TxState = 3; if ((TxCount < 22) && (TxState <= 1)) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } // espera o 8 half cycles (TxCount em 255 para impedir ke quando esperou os 8 hc volte a esta condicao // esta a fazer mais devido a estrutura do programa... mas nao faz mal else if ((TxCount != 255) && (TxState == 2)) { w8hc = 0; TxCount = 255; } else if ((TxCount < 22) && ( (TxState >= 3) && (TxState <= 4))) { if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 5) X10TermTx(); // Determina as passagens para o outro estado if ( ((TxCount == 22) && (TxState <= 1)) || ((w8hc > 8) && (TxState == 2)) || ((TxCount == 22) && ((TxState >= 3) && (TxState <= 4)) ) ) { TxState++;

TDI - Transdutores domóticos inteligentes

Relatório Final 191/276

TxCount = 0; } } // Codigo Extendido else { if (((TxCount < 30) && (TxState == 0)) || ((TxCount < 30) && (TxState == 2))) { if (((TxBuffer1 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (((TxCount < 32) && (TxState == 1)) || ((TxCount < 32) && (TxState == 3))){ if (((TxBuffer2 >> TxCount) & 0x01) == 1) StartPWM(); TxCount++; } else if (TxState == 4) X10TermTx(); if ( ((TxCount == 30) && ((TxState == 0) || (TxState == 2))) || ((TxCount == 32) && ((TxState == 1) || (TxState == 3)))) { TxState++; TxCount = 0; } } } void X10Receive(int1 RxBit) { if (RxStartCode != 0x0E) { // 1110 RxStartCode = RxStartCode << 1; if (RxBit == 1) RxStartCode |= 0x01; RxStartCode &= 0x0F; if (RxStartCode == 0x0E) { RxCounter = 0; RxBuffer1 = 0; RxBuffer2 = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 192/276

RxError[0]=0; RxError[1]=0; // RxExtended = 0; } } else if (RxStartCode == 0x0E) { if (RxCounter < 8) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 7) { RxError[RxState] += check8(RxBuffer1); RxHC[RxState] = decodeX10(RxBuffer1, 'H'); } } else if ((RxCounter >=8) && (RxCounter < 16)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 15) { RxError[RxState] += check8(RxBuffer1); } } else if ((RxCounter >=16) && (RxCounter < 18)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 17) { if (RxBuffer2 == 0x01) { RxDC[RxState] = decodeX10(RxBuffer1, 'U'); RxFC[RxState] = 1;} else if (RxBuffer2 == 0x02) { RxDC[RxState] = decodeX10(RxBuffer1, 'D'); RxFC[RxState] = 2; } else RxError[RxState] += 1; if ((RxDC[RxState] == 8) && (RxFC[RxState] == 2)) {} // Caso n seja um extended code else { RxStartCode=0; if (RxState == 1) { RxState = 0; if (RxError[0] == 0) RxOk = 0;

TDI - Transdutores domóticos inteligentes

Relatório Final 193/276

else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 1; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; } } else RxState = 1; } } } //codigo extendido else if ((RxCounter >=18) && (RxCounter < 26)) { RxBuffer1 <<= 1; if (RxBit == 1) RxBuffer1 |= 0x01; if (RxCounter == 25) { RxError[RxState] += check8(RxBuffer1); RxExtDC[RxState] = decodeX10(RxBuffer1, 'U'); } } else if ((RxCounter >=26) && (RxCounter < 42)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 41) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtData[RxState] = X10decompl(RxBuffer2); } } else if ((RxCounter >=42) && (RxCounter < 58)) { RxBuffer2 <<= 1; if (RxBit == 1) RxBuffer2 |= 0x01; if (RxCounter == 57) { RxError[RxState] += check8((char) RxBuffer2); RxError[RxState] += check8((char) (RxBuffer2 >> 8)); RxExtCommand[RxState] = X10decompl(RxBuffer2);

TDI - Transdutores domóticos inteligentes

Relatório Final 194/276

RxStartCode=0; if (RxState == 1) { if (RxError[0] == 0) RxOk = 0; else if (RxError[1] == 0) RxOk = 1; else RxOk = 2; if (RxOk < 2) { RxComplete = 1; RxExtended = 2; RxHC[0]=RxHC[RxOk]; RxDC[0]=RxDC[RxOk]; RxFC[0]=RxFC[RxOk]; RxExtDC[0]=RxExtDC[RxOk]; RxExtData[0] = RxExtData[RxOk]; RxExtCommand[0] = RxExtCommand[RxOk]; } RxState = 0; } else RxState = 1; } } RxCounter++; } } void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(FALSE);

TDI - Transdutores domóticos inteligentes

Relatório Final 195/276

setup_timer_1(T1_DISABLED); setup_timer_0(RTCC_DIV_64 | RTCC_INTERNAL); setup_timer_2(T2_DIV_BY_4, 3, 1); set_pwm1_duty(2); setup_ccp1(CCP_OFF); set_tris_b(0x0F); set_tris_d(0x00); set_tris_c(0x80); //1000 0000 printf("DC Module\r\n"); // Inicialização de variaveis SetModuleId(1002); ModuleHC = getHC(); ModuleUC = getUC(); ModuleEnable = 0; INTEDG = 0; w8hc = 0; TxBusy = 0; TxState = 0; TxPhase = 0; TxStopPWM = 0; RxComplete = 0; RxStartCode = 0; RxState = 0; LED_ON = 0; LED_OFF = 1; ACT_CTRL = 0; RTCCount = 0; RTCUpdate = 0; RTCOldMin = 255; X10RCVsetClock = 0; X10RCVsetSched = 0; RTCInit(); disable_interrupts(INT_RTCC); enable_interrupts(INT_EXT); enable_interrupts(global);

TDI - Transdutores domóticos inteligentes

Relatório Final 196/276

while(TRUE) { if (RxComplete == 1) { RxComplete = 0; disable_interrupts(INT_EXT); printf("%d HC %c ",RxExtended, RxHC[0]); if (RxExtended == 1) { printf("UC/DC %d (%d)\n\r", RxDC[0], RxFC[0]); } else { printf("%d ", RxExtDC[0]); printf("%d ", RxExtData[0]); printf("%d ", RxExtCommand[0]); } enable_interrupts(INT_EXT); if (RxExtended == 1) { if ((RxFC[0] == 1) && (RxHC[0] == ModuleHC) && (RxDC[0] == ModuleUC)) ModuleEnable = 1; else if (RxFC[0] == 1) ModuleEnable = 0; } else if (RxExtended == 2) { if ( (RxExtCommand[0] == 0x61) && (RxExtData[0] == (getModuleId() & 0xFF)) ) SerialNConfig++; else if ( (RxExtCommand[0] == 0x62) && (RxExtData[0] == ((getModuleId() >> 8) & 0xFF)) ) SerialNConfig++; else SerialNConfig=0; if ((RxHC[0] == ModuleHC) && (RxExtDC[0] == ModuleUC)) ModuleEnable = 1; } //Altera HC e UC via serial Number if (SerialNConfig == 2) { SerialNConfig = 0; setHC(RxHC[0]); setUC(RxExtDC[0]);

TDI - Transdutores domóticos inteligentes

Relatório Final 197/276

ModuleHC = getHC(); ModuleUC = getUC(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } else if ((RxExtended == 2) && (ModuleEnable == 1)) { // Change HC e UC if (RxExtCommand[0] == 0x63) { setHC(((RxExtData[0] >> 4) & 0x0F) + 65); setUC((RxExtData[0] & 0x0F) + 1); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma ModuleHC = getHC(); ModuleUC = getUC(); } //Set Schedules if (RxExtCommand[0] == 0x65) { X10RCVOption = (RxExtData[0] >> 4) & 0x0F; X10RCVCommand = RxExtData[0] & 0x0F; if (X10RCVOption == 0x0F) { putc('C'); ScheduleClear(); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } X10RCVsetSched = 1; X10RCVCount = 0; X10RCVOption = 0; X10RCVCommand = 0; X10RCVHour = 0; X10RCVMin = 0; X10RCVMonth = 0; X10RCVYear = 0; X10RCVDoM = 0; X10RCVDoW = 0; } //Set RTC if (RxExtCommand[0] == 0x66) { X10RCVsetClock = 1; X10RCVCount = 0; } //Ano if (RxExtCommand[0] == 0x6B) { X10RCVYear = RxExtData[0]; X10RCVCount ++; } //Mes if (RxExtCommand[0] == 0x6A) {

TDI - Transdutores domóticos inteligentes

Relatório Final 198/276

X10RCVMonth = RxExtData[0]; X10RCVCount ++; } //Dia do Mes if (RxExtCommand[0] == 0x6C) { X10RCVDoM = RxExtData[0]; X10RCVCount ++; } //Dia da Semana if (RxExtCommand[0] == 0x6D) { X10RCVDoW = RxExtData[0]; X10RCVCount ++; } //Hora if (RxExtCommand[0] == 0x67) { X10RCVHour = RxExtData[0]; X10RCVCount ++; } //Min if (RxExtCommand[0] == 0x68) { X10RCVMin = RxExtData[0]; X10RCVCount ++; } //Sec if (RxExtCommand[0] == 0x69) { X10RCVSec = RxExtData[0]; X10RCVCount ++; } //End if (RxExtCommand[0] == 0x6F) { if (X10RCVsetClock == 1) { if (X10RCVCount == 7) { printf("acerta relogio"); RTCSetTimeDate(X10RCVSec, X10RCVMin, X10RCVHour, X10RCVDoW, X10RCVDoM, X10RCVMonth, X10RCVYear); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } } if (X10RCVsetSched == 1) {

TDI - Transdutores domóticos inteligentes

Relatório Final 199/276

if (((X10RCVOption == 1) && (X10RCVOption == 1)) || ((X10RCVOption == 2) && (X10RCVOption == 2)) || ((X10RCVOption == 3) && (X10RCVOption == 3)) || ((X10RCVOption == 4) && (X10RCVOption == 3)) || ((X10RCVOption == 5) && (X10RCVOption == 4)) || ((X10RCVOption == 2) && (X10RCVOption == 5))) setSchedule(X10RCVOption, X10RCVHour, X10RCVMin, X10RCVDoM, X10RCVDoW, X10RCVMonth, X10RCVYear, X10RCVCommand); printf("\r\n venho aki %d\r\n", a); sendX10(1, 0, ModuleHC, ModuleUC, 0, 0x00, 0x60); // Confirma } X10RCVsetSched = 0; X10RCVsetClock = 0; X10RCVCount = 0; } } else if ((RxHC[0] == ModuleHC) && (RxFC[0] == 2) && (ModuleEnable == 1)) { if ((RxDC[0] == 1) || (RxDC[0] == 5)) {// ON e ALL LIGHTS ON ACT_CTRL = 1; LED_OFF = 0; LED_ON = 1; } else if ((RxDC[0] == 2) || (RxDC[0] == 6) || (RxDC[0] == 7)) { // OFF, ALL UNITS OFF e ALL LIGHTS OFF ACT_CTRL = 0; LED_OFF = 1; LED_ON = 0; } else if (RxDC[0] == 9) { // Hail Request sendX10(0, 0, ModuleHC, ModuleUC, 10, 0, 0); //HAIL ACK } else if (RxDC[0] == 16) { // Status request if (ACT_CTRL == 1) sendX10(0, 0, ModuleHC, ModuleUC, 14, 0, 0); // Status ON else sendX10(0, 0, ModuleHC, ModuleUC, 15, 0, 0); // Status OFF }

TDI - Transdutores domóticos inteligentes

Relatório Final 200/276

} } if (TxBusy == 0) { if (RTCUpdate == 1) { RTCUpdate = 0; RTCUpdateTime(); if (RTCOldMin != RTCMin) { RTCOldMin = RTCMin; SchedCommand = checkSchedules(); if (SchedCommand == 1) { ACT_CTRL = 1; LED_OFF = 0; LED_ON = 1; } else if (SchedCommand == 2) { ACT_CTRL = 0; LED_OFF = 1; LED_ON = 0; } } } if (BUTTON_ON == 0) { ACT_CTRL = 1; LED_ON = 1; LED_OFF = 0; } else if (BUTTON_OFF == 0) { ACT_CTRL = 0; LED_OFF = 1; LED_ON = 0; }

TDI - Transdutores domóticos inteligentes

Relatório Final 201/276

if (kbhit()) { RSBuffer = getc(); if (RSBuffer == '1') { disable_interrupts(INT_EXT); printEeprom(0xFF); enable_interrupts(INT_EXT); } else if (RSBuffer == '2') { disable_interrupts(INT_EXT); RTCGetCompleteTime(); printf("\r\n%U:%U:%U %U / %U / %U Dia da Semana %U\r\n", RTCHour, RTCMin, RTCSec, RTCDofM, RTCMonth, RTCYear, RTCDofW); enable_interrupts(INT_EXT); } else if (RSBuffer == '3') { disable_interrupts(INT_EXT); printf("\r\nHC - %c UC - %d\r\n", GetHC(), GetUC()); enable_interrupts(INT_EXT); } } } } }

TDI - Transdutores domóticos inteligentes

Relatório Final 202/276

ANEXO B - CÓDIGO FONTE DO BOOTLOADER PARA O MICRO-CONTROLADOR.

Programa bootloader.c #include <16F877A.h> #use delay(clock=7680000) #fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP #use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) #define LOADER_BEGIN 0x1CB0 #define LOADER_END 0x1FFF #define RS_START 0x02 #define RS_FINISH 0x04 #define RS_NEXT 0x06 #define RS_REPEAT 0x15 #define RS_OVERWRITE 0x18 #bit WR = 0x18C.1 #bit EEPGD = 0x18C.7 #bit WREN = 0x18C.2 #byte EECON2 = 0x18D #byte EEDATA = 0x10C #byte EEADR = 0x10D #byte EEDATH = 0x10E #byte EEADRH = 0x10F #ORG LOADER_BEGIN, LOADER_END auto=0 default void write_program(unsigned int16 addr, unsigned int16 data) { EEADRH = ((addr >> 8) & 0x00FF); EEADR = addr & 0x00FF; EEDATH = ((data >> 8) & 0x00FF); EEDATA = data & 0x00FF; EEPGD = 1; WREN = 1;

TDI - Transdutores domóticos inteligentes

Relatório Final 203/276

EECON2 = 0x55; EECON2 = 0xAA; WR = 1; #asm NOP NOP #endasm WREN = 0; } // a slim version of atoi(). // converts ascii text to integer // i.e. '1' = 1, 'A' = 10 unsigned int a2i(unsigned char asciiByte) { if (asciiByte >= 'A' && asciiByte <= 'F') return((asciiByte) - 'A' + 10); else if (asciiByte >= '0' && asciiByte <= '9') return( asciiByte - '0'); } // convert two ascii text to a 8 bit integer unsigned int read8() { return( (a2i(getc()) << 4) + (a2i(getc())) ); } void main() { int1 notDone = 1; unsigned int recSize, recType, checksum, recChecksum; unsigned int16 writeAddr, Buffer[10]; unsigned char i, j; unsigned int16 UserBootVectorAddr; unsigned int UserBootMod; unsigned int16 readAddr; unsigned int16 temp; char c;

TDI - Transdutores domóticos inteligentes

Relatório Final 204/276

printf("FEUP PIC BootLoader v1.0\r\nPress 'l' for firmware upload\r\n"); while (!kbhit()); if (getc()=='l') { UserBootVectorAddr=label_address(UserBootVector); UserBootMod = UserBootVectorAddr % 4; printf("Waiting for HEX file...\r\n"); putc(RS_START); while(notDone) { while (getc() != ':'); checksum = 0; recSize = read8(); checksum += recSize; recSize >>= 1; writeAddr = ((int16)read8() << 8) + read8(); checksum += (WriteAddr & 0x00FF); checksum += ((WriteAddr >> 8) & 0x00FF); writeAddr >>=1; recType = read8(); if (recType == 0x01) { notDone = 0; putc(RS_FINISH); } else if (recType == 0x00) { for (i=0; i < recSize; i++) { Buffer[i] = read8() + ((int16) read8() << 8); checksum += (Buffer[i] & 0x00FF); checksum += ((Buffer[i] >> 8) & 0x00FF); } recChecksum = read8();

TDI - Transdutores domóticos inteligentes

Relatório Final 205/276

// Escreve para a memoria if (((recChecksum + checksum) & 0x00FF) == 0x00) { // if data is in the EEPROM area if ((writeAddr >= 0x2100) && (writeAddr <= 0x21FF)) { write_eeprom((int) writeAddr, (int) Buffer[i]); putc(RS_NEXT); } // else if data is in the Configuration register area else if ((writeAddr >= 0x2000) && (writeAddr <= 0x20FF)) putc(RS_NEXT); // else if data overlaps the bootloader code -> halt else if ((writeAddr >= LOADER_BEGIN) && (writeAddr <= LOADER_END)) putc(RS_OVERWRITE); // else -> data is in program area else { for (i=0; i<recSize ;i++) { if ((writeAddr < 0x004) && (i<4) ) { if ((UserBootMod != 0) && (i==0)) { for (j = UserBootMod; j >= 1; j--) { readAddr = read_program_eeprom(UserBootVectorAddr - j); write_program(UserBootVectorAddr - j, readAddr); } } write_program(UserBootVectorAddr + i, Buffer[i]); if ((UserBootMod != 0) && (i == 3)) { // putc('c');

TDI - Transdutores domóticos inteligentes

Relatório Final 206/276

for (j = 1; j <= 4 - UserBootMod ; j++) { // putc('d'); readAddr = read_program_eeprom(UserBootVectorAddr + i + j); write_program(UserBootVectorAddr + i + j, readAddr); } } } else { write_program(writeAddr + i, Buffer[i]); if ( ((recSize != 8) || (recSize != 4)) && (i == (recSize - 1)) ) { if (recSize < 4) for (j = 1; j <= 4 - recSize; j++) { readAddr = read_program_eeprom(writeAddr + i + j); write_program(writeAddr + i + j, readAddr); } else for (j = 1; j <= 8 - recSize; j++) { readAddr = read_program_eeprom(writeAddr + i + j); write_program(writeAddr + i + j, readAddr); } } } } // Pedido para a proxima linha putc(RS_NEXT); } } // Pedido para a repetição da linha else putc(RS_REPEAT); } } }

TDI - Transdutores domóticos inteligentes

Relatório Final 207/276

UserBootVector: #asm MOVLW 0x00 MOVWF 0x0A GOTO 0x00 NOP NOP #endasm } #ORG default

TDI - Transdutores domóticos inteligentes

Relatório Final 208/276

ANEXO C - CÓDIGO FONTE DA APLICAÇÃO GRÁFICA “BOOTLOADER”

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Registry, CPort, ExtCtrls; type TForm1 = class(TForm) StatusBar: TStatusBar; LoadButton: TButton; FileNameEdit: TEdit; Label1: TLabel; ComComboBox: TComboBox; ProgramButton: TButton; SetCOMButton: TButton; OpenDialog: TOpenDialog; QuitButton: TButton; ComPort: TComPort; ProgressBar: TProgressBar; Timer: TTimer; Label2: TLabel; procedure LoadButtonClick(Sender: TObject); procedure QuitButtonClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure SetCOMButtonClick(Sender: TObject); procedure ComPortRxChar(Sender: TObject; Count: Integer); procedure ProgramButtonClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure TimerTimer(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; RecordFileDesc : TextFile; RecordFileName : String; RecordLine : array[1..8000] of String; RecordLinesCount : integer; RecordTotalLines : integer; Buffer : String;

TDI - Transdutores domóticos inteligentes

Relatório Final 209/276

implementation {$R *.dfm} procedure TForm1.LoadButtonClick(Sender: TObject); begin if OpenDialog.Execute then begin RecordFileName := OpenDialog.FileName; FileNameEdit.Text:= RecordFileName; AssignFile(RecordFileDesc, RecordFileName); try if SysUtils.FileExists(RecordFileName) then Begin Append(RecordFileDesc); // If existing file Reset(RecordFileDesc); RecordLinesCount := 0; while not eof(RecordFileDesc) do Begin inc(RecordLinesCount); Readln(RecordFileDesc, RecordLine[RecordLinesCount]); End; ProgramButton.Enabled:=True; RecordTotalLines := RecordLinesCount; ProgressBar.Max:=RecordTotalLines-1; StatusBar.Panels[0].Text:='File loaded!'; End else MessageDlg('Cannot Open File', mtError, [mbOK], 0); EXCEPT // Ignore exceptions while writing log files END; CloseFile(RecordFileDesc); end; end; procedure TForm1.QuitButtonClick(Sender: TObject); begin ComPort.Close;

TDI - Transdutores domóticos inteligentes

Relatório Final 210/276

Close; end; procedure TForm1.FormActivate(Sender: TObject); var reg: TRegistry; st: Tstrings; i: Integer; begin ComComboBox.Items.Clear; reg := TRegistry.Create; try reg.RootKey := HKEY_LOCAL_MACHINE; reg.OpenKey('hardware\devicemap\serialcomm', False); st := TstringList.Create; try reg.GetValueNames(st); for i := 0 to st.Count - 1 do ComComboBox.Items.Add(reg.Readstring(st.strings[i])); finally st.Free; end; reg.CloseKey; finally reg.Free; end; ComComboBox.ItemIndex:=0; StatusBar.Panels[0].Text:='Load HEX file!'; StatusBar.Panels[1].Text:=ComPort.Port; ProgressBar.Min:=0; ProgressBar.Position:=0; ProgressBar.Max:=1; Timer.Enabled:=False; end; procedure TForm1.SetCOMButtonClick(Sender: TObject); begin ComPort.Port:=ComComboBox.Items.Strings[ComComboBox.ItemIndex]; StatusBar.Panels[1].Text:=ComPort.Port; end; procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer); var i : integer; j : integer;

TDI - Transdutores domóticos inteligentes

Relatório Final 211/276

begin ComPort.ReadStr(Buffer, Count); for i := 1 to Count do begin // Começa a transmissão (RS_START) if (Buffer[i] = chr(2)) then Begin RecordLinesCount := 1; for j:=1 to length(RecordLine[RecordLinesCount]) do ComPort.TransmitChar(RecordLine[RecordLinesCount][j]); End // Pede a proxima linha (RS_NEXT) Else if (Buffer[i]= chr(6)) then Begin ProgressBar.Position:= RecordLinesCount; // Memo1.lines.add('Linha ' + IntToStr(RecordLinesCount) + ' ok'); inc(RecordLinesCount); for j:=1 to length(RecordLine[RecordLinesCount]) do ComPort.TransmitChar(RecordLine[RecordLinesCount][j]); End // Repete a linha Else if (Buffer[i]= chr(21)) then Begin for j:=1 to length(RecordLine[RecordLinesCount]) do ComPort.TransmitChar(RecordLine[RecordLinesCount][j]); End // Termina a transmissão Else if (Buffer[i]= chr(4)) then Begin MessageDlg('PIC sucessfully programmed!', mtInformation, [mbOK], 0); ProgressBar.Position:=0; StatusBar.Panels[0].Text:='Done'; Timer.Enabled:=True; End; end; end; procedure TForm1.ProgramButtonClick(Sender: TObject); begin ComPort.Open;

TDI - Transdutores domóticos inteligentes

Relatório Final 212/276

if MessageDlg('Please reset PIC and press OK', mtInformation, [mbOK], 0) = mrOK then Begin ComPort.TransmitChar('l'); StatusBar.Panels[0].Text:='Programming PIC...'; End; end; procedure TForm1.Button1Click(Sender: TObject); begin ComPort.Close; end; procedure TForm1.TimerTimer(Sender: TObject); begin ComPort.Close; Timer.Enabled:=False; end; end.

TDI - Transdutores domóticos inteligentes

Relatório Final 213/276

ANEXO D - CÓDIGO FONTE DA APLICAÇÃO GRÁFICA “X-10 INTERFACE PARA PC

program X10; uses Forms, Unit1 in 'Unit1.pas' {MainForm}, Unit2 in 'Unit2.pas' {ComPortSettings}, Unit3 in 'Unit3.pas' {SnifferForm}, Unit4 in 'Unit4.pas' {AddModuleForm}, Unit6 in 'Unit6.pas' {EditModuleForm}, Unit5 in 'Unit5.pas' {AboutForm}, Unit7 in 'Unit7.pas' {ModuleSettingsForm}, Unit8 in 'Unit8.pas' {ScheduleSettingsForm}, Unit9 in 'Unit9.pas' {SendingForm}; {$R *.res} begin Application.Initialize; Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TComPortSettings, ComPortSettings); Application.CreateForm(TSnifferForm, SnifferForm); Application.CreateForm(TAddModuleForm, AddModuleForm); Application.CreateForm(TEditModuleForm, EditModuleForm); Application.CreateForm(TAboutForm, AboutForm); Application.CreateForm(TModuleSettingsForm, ModuleSettingsForm); Application.CreateForm(TScheduleSettingsForm, ScheduleSettingsForm); Application.CreateForm(TSendingForm, SendingForm); Application.Run; end. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, CPort, ComCtrls, TabNotBk, Menus, Registry, StrUtils, ExtCtrls; type TMainForm = class(TForm) Memo: TMemo; ComPort: TComPort; LigarButton: TButton;

TDI - Transdutores domóticos inteligentes

Relatório Final 214/276

LimparButton: TButton; MemoTemp: TMemo; MainMenu1: TMainMenu; File1: TMenuItem; Quit1: TMenuItem; OpenConfiguration1: TMenuItem; Save1: TMenuItem; Saveas1: TMenuItem; Configuration1: TMenuItem; Modules1: TMenuItem; About1: TMenuItem; SetDefaultConfig: TMenuItem; Tools1: TMenuItem; DownloadModuleSettings1: TMenuItem; AllLightsOff1: TMenuItem; AllUnitsOff1: TMenuItem; Add1: TMenuItem; ComPortSettings1: TMenuItem; Delete1: TMenuItem; StatusBar: TStatusBar; Label2: TLabel; ModuleListBox: TListBox; GroupBox1: TGroupBox; NameLabel: TLabel; TypeLabel: TLabel; HCLabel: TLabel; UCLabel: TLabel; StatusLabel: TLabel; ScheduleButton: TButton; StatusButton: TButton; StatusEdit: TEdit; HCEdit: TEdit; UCEdit: TEdit; NameEdit: TEdit; TypeEdit: TEdit; ControlLabel: TLabel; ControlONButton: TButton; ControlOFFButton: TButton; DBLabel: TLabel; ControlBRIGHTButton: TButton; ControlDIMButton: TButton; SnifferMode1: TMenuItem; Timer: TTimer; PluggedLabel: TLabel; PluggedEdit: TEdit; PluggedButton: TButton; Image1: TImage; Button3: TButton; Edit1: TEdit;

TDI - Transdutores domóticos inteligentes

Relatório Final 215/276

Button5: TButton; SerialNLabel: TLabel; SerialNEdit: TEdit; Edit2: TMenuItem; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; ModSettingsButton: TButton; Button1: TButton; TimerResponse: TTimer; procedure ComPortRxChar(Sender: TObject; Count: Integer); procedure LigarButtonClick(Sender: TObject); procedure LimparButtonClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Quit1Click(Sender: TObject); procedure ComPortSettings1Click(Sender: TObject); procedure ModuleListBoxClick(Sender: TObject); procedure TimerTimer(Sender: TObject); function GetModuleIndex : integer; procedure SendtoQueue(Extended:integer; HC:char; UC:integer; DC:integer; CC:integer); procedure ActivateX10Send; procedure UpdateX10Sniffer(Extended : char; HC : char; DC : char; FC : char; Data : char; Command : char); procedure ControlONButtonClick(Sender: TObject); procedure ControlOFFButtonClick(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure SnifferMode1Click(Sender: TObject); procedure ControlBRIGHTButtonClick(Sender: TObject); procedure ControlDIMButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Add1Click(Sender: TObject); procedure SaveModuleIni; procedure UpdateDetails(ModuleIndex : integer); function X10Decode(DC : char) : string; procedure LoadModulesIni; procedure UpdateModulesList; procedure Delete1Click(Sender: TObject); procedure Edit2Click(Sender: TObject); procedure SetDefaultConfigClick(Sender: TObject); procedure About1Click(Sender: TObject); procedure OpenConfiguration1Click(Sender: TObject); procedure Saveas1Click(Sender: TObject); procedure Save1Click(Sender: TObject);

TDI - Transdutores domóticos inteligentes

Relatório Final 216/276

procedure PluggedButtonClick(Sender: TObject); procedure StatusButtonClick(Sender: TObject); procedure ModSettingsButtonClick(Sender: TObject); procedure ScheduleButtonClick(Sender: TObject); procedure ShowSendingWindow(text : string; WaitConfirm : boolean; timeout: integer; form : string); procedure UpdateX10Details(HC : char; DC : char; FC : char); function FindModule(HC : Char; UC : integer) : integer; private { Private declarations } public { Public declarations } end; PModule = ^TModule; TModule = record name, typeName : String; modTypeA : Byte; lampFunc, timerFunc, modTypeB : Byte; serialN : Word; HC : Char; UC : Integer; hail, status : byte; end; PQueue = ^TQueue; TQueue = record Extended : integer; HC : Char; UC, DC, CC : Integer; end; Const maxModules = 255; YES = 2; NO = 1; X10ON = 1; X10OFF = 2; X10DIM = 3; X10BRIGHT = 4; X10ALLLIGHTSON = 5; X10ALLUNITSOFF = 6; X10ALLLIGHTSOFF = 7; X10EXTCODE1 = 8; X10HAILREQ = 9;

TDI - Transdutores domóticos inteligentes

Relatório Final 217/276

X10HAILACK = 10; X10EXTCODE3 = 11; X10UNUSED = 12; X10EXTCODE2 = 13; X10STATUSON = 14; X10STATUSOFF = 15; X10STATUSREQ = 16; // Extended Code (0111 1) - type 6 X10CONFIRM = $60; X10EXTLSBSERIAL = $61; X10EXTMSBSERIAL = $62; X10EXTCHANGEHUC = $63; X10EXTCONFSENSOR = $64; X10EXTSCHOPTION = $65; X10EXTSETCLOCK = $66; X10EXTSETHOUR = $67; X10EXTSETMIN = $68; X10EXTSETSEC = $69; X10EXTSETMONTH = $6A; X10EXTSETYEAR = $6B; X10EXTSETDOM = $6C; X10EXTSETDOW = $6D; X10EXTSETEND = $6F; var MainForm: TMainForm; module: array[0..MaxModules] of PModule; queue: array[0..9] of PQueue; queueSize : integer; queuePos : integer; modulesIni : String; modulesFileD, snifferD : TextFile; RSBuffer: array[1..255] of char; RSCount : integer; RSCommandRec : boolean; RSInitCommandRec : boolean; RSConnect : boolean; RSSending : boolean; RSConfirmation : integer; SendingActiveForm : string; ActiveModuleHC : char;

TDI - Transdutores domóticos inteligentes

Relatório Final 218/276

ActiveModuleUC : integer; implementation uses Unit2, Unit3, Unit4, Unit6, Unit5, Unit7, Unit8, Unit9; {$R *.dfm} procedure TMainForm.ShowSendingWindow(text : string; WaitConfirm : boolean; timeout: integer; form : string); Begin SendingActiveForm := form; if WaitConfirm = TRUE then RSConfirmation := 1 else RSConfirmation := 0; SendingForm.Timer1.Interval:= 50; SendingForm.ProgressBar1.Min:=0; SendingForm.ProgressBar1.Max:=10; SendingForm.ProgressBar1.Position:=0; SendingForm.Timer1.Enabled:=true; SendingForm.label1.Caption:=text; SendingForm.Timer3.Interval:=timeout * 1000; SendingForm.Timer3.enabled:=true; if SendingActiveForm = 'MainForm' then MainForm.Enabled:=False; if SendingActiveForm = 'ModuleSettingsForm' then ModuleSettingsForm.Enabled:=False; if SendingActiveForm = 'ScheduleSettingsForm' then ScheduleSettingsForm.Enabled:=False; SendingForm.Show; End; procedure TMainForm.LoadModulesIni; var buffer : string; ModCount : integer; strTemp : string; Begin ModCount := -1; AssignFile(modulesFileD, modulesIni); try if SysUtils.FileExists(modulesIni) then Append(modulesFileD) // If existing file else Rewrite(modulesFileD); // Create if new

TDI - Transdutores domóticos inteligentes

Relatório Final 219/276

EXCEPT // Ignore exceptions while writing log files END; Reset(modulesFileD); while not eof(modulesFileD) do Begin Readln(modulesFileD, buffer); if AnsiContainsText(buffer , '[MODULE]') then Begin inc(ModCount); new(Module[ModCount]); End; if AnsiContainsText(buffer , 'NAME=') then Module[ModCount].name:= AnsiMidStr(buffer, 6, length(buffer)); if AnsiContainsText(buffer , 'TYPEN=') then Module[ModCount].typeName:= AnsiMidStr(buffer, 7, length(buffer)); if AnsiContainsText(buffer , 'TYPEA=') then Module[ModCount].modTypeA:= strtoint(AnsiMidStr(buffer, 7, length(buffer))); if AnsiContainsText(buffer , 'TYPEB=') then Module[ModCount].modTypeB:= strtoint(AnsiMidStr(buffer, 7, length(buffer))); if AnsiContainsText(buffer , 'LAMPFUNC=') then Module[ModCount].lampFunc:= strtoint(AnsiMidStr(buffer, 10, length(buffer))); if AnsiContainsText(buffer , 'TIMERFUNC=') then Module[ModCount].timerFunc:= strtoint(AnsiMidStr(buffer, 11, length(buffer))); if AnsiContainsText(buffer , 'SERIALN=') then Module[ModCount].serialN:= strtoint(AnsiMidStr(buffer, 9, length(buffer))); if AnsiContainsText(buffer , 'HC=') then begin strTemp := AnsiMidStr(buffer, 4, length(buffer)); Module[ModCount].HC:= strTemp[1]; end; if AnsiContainsText(buffer , 'UC=') then Module[ModCount].UC:= strtoint(AnsiMidStr(buffer, 4, length(buffer))); Module[ModCount].hail:=0; Module[ModCount].status:=0; End; CloseFile(modulesFileD);

TDI - Transdutores domóticos inteligentes

Relatório Final 220/276

End; procedure TMainForm.SaveModuleIni; var ModCount : integer; begin ModCount := 0; AssignFile(modulesFileD, ModulesIni); Rewrite(modulesFileD); // Create if new while module[ModCount] <> NIL do begin if module[ModCount].name <> '' then Begin Writeln(modulesFileD, '[MODULE]'); Writeln(modulesFileD, 'NAME=' + module[ModCount].name); Writeln(modulesFileD, 'TYPEN=' + module[ModCount].typename); Writeln(modulesFileD, 'TYPEA=' + IntToStr(module[ModCount].modTypeA)); Writeln(modulesFileD, 'TYPEB=' + IntToStr(module[ModCount].modTypeB)); Writeln(modulesFileD, 'LAMPFUNC=' + IntToStr(module[ModCount].lampFunc)); Writeln(modulesFileD, 'TIMERFUNC=' + IntToStr(module[ModCount].timerFunc)); Writeln(modulesFileD, 'SERIALN=' + IntToStr(module[ModCount].serialN)); Writeln(modulesFileD, 'HC=' + module[ModCount].HC); Writeln(modulesFileD, 'UC=' + IntToStr(module[ModCount].UC)); Writeln(modulesFileD, ''); end; inc(ModCount); End; CloseFile(modulesFileD); end; function TMainForm.X10Decode(DC : char) : string; begin case DC of chr(1) : X10Decode:= 'ON'; chr(2) : X10Decode:= 'OFF'; chr(3) : X10Decode:= 'DIM'; chr(4) : X10Decode:= 'BRIGHT'; chr(5) : X10Decode:= 'ALL LIGHTS ON';

TDI - Transdutores domóticos inteligentes

Relatório Final 221/276

chr(6) : X10Decode:= 'ALL UNITS OFF'; chr(7) : X10Decode:= 'ALL LIGHTS OFF'; chr(8) : X10Decode:= 'EXTENDED CODE 1'; chr(9) : X10Decode:= 'HAIL REQUEST'; chr(10) : X10Decode:= 'HAIL ACKNOWLEDGE'; chr(11) : X10Decode:= 'EXTENDED CODE 3'; chr(12) : X10Decode:= 'UNSED'; chr(13) : X10Decode:= 'EXTENDED CODE 2'; chr(14) : X10Decode:= 'STATUS ON'; chr(15) : X10Decode:= 'STATUS OFF'; chr(16) : X10Decode:= 'STATUS REQUEST'; else X10Decode:= 'UNKNOWN'; end; end; function TMainForm.FindModule(HC : Char; UC : integer) : integer; var i : integer; begin for i:=1 to MaxModules do if Module[i] <> NIL then begin if ((Module[i].HC = HC) and (Module[i].UC = UC)) then begin FindModule:=i; break; end; end else begin FindModule:=255; break; end; end; procedure TMainForm.UpdateX10Details(HC : char; DC : char; FC : char); var i : integer; begin memotemp.text:= memotemp.text + 'HC ' + HC + ' DC ' + inttostr(ord(DC)) + ' FC ' + inttostr(ord(FC)); ActiveModuleHC:= HC; if (FC = chr(1)) then ActiveModuleUC:=ord(DC); if (FC = chr(2)) then begin i:= FindModule(ActiveModuleHC, ActiveModuleUC); memotemp.Text:=inttostr(i);

TDI - Transdutores domóticos inteligentes

Relatório Final 222/276

if i <> 255 then begin if (DC = chr(X10HAILACK)) then Module[i].hail:=1; if (DC = chr(X10STATUSOFF)) then Module[i].status:=1; if (DC = chr(X10STATUSON)) then Module[i].status:=2; end; UpdateDetails(GetModuleIndex); end; end; procedure TMainForm.UpdateX10Sniffer(Extended : char; HC : char; DC : char; FC : char; Data : char; Command : char); var s : string; Date: TDateTime; begin s:='<' + DateTimeToStr(Now) + '> '; if (Extended = chr(1)) then begin if FC = chr(1) then s:=s + 'Module with House Code ' + HC + ' and Unit Code ' + inttostr(ord(DC)) + ' active'; if FC = chr(2) then s:=s + 'Command ' + X10Decode(DC) + ' received'; end; SnifferForm.SnifferListBox.Items.Insert(0, s); end; procedure TMainForm.ActivateX10Send(); begin RSSending:=True; UpdateDetails(GetModuleIndex); ComPort.TransmitChar(chr(22)); //Inicio de transmissao ComPort.TransmitChar(chr(2)); ComPort.TransmitChar(chr(queue[queuePos].Extended)); ComPort.TransmitChar(queue[queuePos].HC); ComPort.TransmitChar(chr(queue[queuePos].UC)); ComPort.TransmitChar(chr(queue[queuePos].DC)); if queue[queuePos].Extended = YES then ComPort.TransmitChar(chr(queue[queuePos].CC)); ComPort.TransmitChar(chr(23));

TDI - Transdutores domóticos inteligentes

Relatório Final 223/276

inc(queuePos); end; procedure TMainForm.SendtoQueue(Extended:integer; HC:char; UC:integer; DC:integer; CC:integer); begin queue[queueSize].Extended:=Extended; queue[queueSize].HC:=HC; queue[queueSize].UC:=UC; queue[queueSize].DC:=DC; queue[queueSize].CC:=CC; inc(queueSize); end; function TMainForm.GetModuleIndex : integer; var i : integer; begin if ModuleListBox.ItemIndex = -1 then GetModuleIndex:=-1 else for i:=0 to MaxModules do if (AnsiCompareText(ModuleListBox.Items.Strings[ModuleListBox.ItemIndex], Module[i].Name) = 0) then begin GetModuleIndex:=i; break; end; end; procedure TMainForm.UpdateDetails(ModuleIndex : integer); var i : integer; begin ControlONButton.Enabled:=FALSE; ControlOFFButton.Enabled:=FALSE; ControlDIMButton.Enabled:=FALSE; ControlBRIGHTButton.Enabled:=FALSE; PluggedButton.Enabled:=False; StatusButton.Enabled:=False; ScheduleButton.Enabled:=False; ModSettingsButton.Enabled:=False; if ModuleIndex = -1 then Begin

TDI - Transdutores domóticos inteligentes

Relatório Final 224/276

NameEdit.Text:=''; TypeEdit.Text:=''; HCEdit.Text:=''; UCEdit.Text:=''; End Else Begin NameEdit.Text:=Module[ModuleIndex].name; TypeEdit.Text:=Module[ModuleIndex].typeName; if Module[ModuleIndex].serialN = 0 then SerialNEdit.Text:='n.a.' else SerialNEdit.Text:=inttostr(Module[ModuleIndex].serialN); HCEdit.Text:=Module[ModuleIndex].HC; UCEdit.Text:=inttostr(Module[ModuleIndex].UC); if Module[ModuleIndex].hail=0 then PluggedEdit.Text:='n.a.' else PluggedEdit.Text:='Yes'; if Module[ModuleIndex].status=0 then StatusEdit.Text:='n.a.' else if Module[ModuleIndex].status=1 then StatusEdit.Text:='Off' else if Module[ModuleIndex].status=2 then StatusEdit.Text:='On'; if ((RSConnect = TRUE) AND (RSSending = FALSE)) then Begin if ((Module[ModuleIndex].modTypeA = 2) or (Module[ModuleIndex].modTypeA = 3))then begin PluggedButton.Enabled:=True; StatusButton.Enabled:=True; end; if Module[ModuleIndex].modTypeB = 2 then begin ControlONButton.Enabled:=TRUE; ControlOFFButton.Enabled:=TRUE; end; if Module[ModuleIndex].lampFunc = 1 then begin ControlDIMButton.Enabled:=TRUE; ControlBRIGHTButton.Enabled:=TRUE; end; if Module[ModuleIndex].lampFunc = 1 then begin ControlDIMButton.Enabled:=TRUE; ControlBRIGHTButton.Enabled:=TRUE; end;

TDI - Transdutores domóticos inteligentes

Relatório Final 225/276

if Module[ModuleIndex].timerFunc = 1 then begin ScheduleButton.Enabled:=True; end; if Module[ModuleIndex].modTypeA = 3 then begin ModSettingsButton.Enabled:=True; end; End else begin end; end; end; procedure TMainForm.UpdateModulesList; var ModCount : integer; begin ModCount := 0; ModuleListBox.Clear; while module[ModCount] <> NIL do begin if Module[ModCount].Name <> '' then ModuleListBox.Items.Add(Module[ModCount].Name); inc(ModCount); end; end; procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer); var buffer : string; i : integer; begin ComPort.ReadStr(buffer, Count); for i := 1 to Count do

TDI - Transdutores domóticos inteligentes

Relatório Final 226/276

begin Memo.Text:= Memo.Text + buffer[i]; MemoTemp.Text:= MemoTemp.Text + inttostr(ord(buffer[i])) + ' '; if buffer[i] = chr(22) then begin RSCount:= 1; RSInitCommandRec:=True; RSBuffer[RSCount] := buffer[i]; inc(RSCount); end else if buffer[i] = chr(23) then begin RSInitCommandRec:=False; RSCommandRec:=true; RSBuffer[RSCount] := buffer[i]; End Else Begin RSBuffer[RSCount] := buffer[i]; inc(RSCount); End; end; if RSCommandRec = true then begin if RSBuffer[1] = chr(22) then begin if RSBuffer[2] = chr(1) then begin if AnsiContainsText(RSBuffer , 'CONNECT OK') then begin Timer.Enabled:=false; RSConnect:=true; LigarButton.Caption:='Disconnect from FEUP X-10 PC Module'; StatusBar.Panels.Items[0].Text:='Connected to FEUP X-10 PC Module'; Tools1.Enabled:=true; UpdateDetails(GetModuleIndex); end else if AnsiContainsText(RSBuffer , 'SENT') then Begin if (queuePos <> queueSize) then ActivateX10Send() else begin

TDI - Transdutores domóticos inteligentes

Relatório Final 227/276

queuePos:=0; queueSize:=0; RSSending:=False; UpdateDetails(GetModuleIndex); end; End; end // Comando X-10 else if RSBuffer[2] = chr(2) then begin // Código normal if RSBuffer[3] = chr(1) then begin UpdateX10Details(RSBuffer[4], RSBuffer[5], RSBuffer[6]); UpdateX10Sniffer(RSBuffer[3], RSBuffer[4], RSBuffer[5], RSBuffer[6], chr(0), chr(0)); end // Código extendido else begin // edit1.Text:=inttostr(ord(buffer[7])); if RSBuffer[7] = chr($60) then begin RSConfirmation:=2; edit1.Text:='aaaa'; end; UpdateX10Sniffer(RSBuffer[3], RSBuffer[4], RSBuffer[5], chr(0), RSBuffer[6], RSBuffer[7]); end; end; end; RSCommandRec := FALSE; for i := 1 to 255 do RSBuffer[i]:=chr(0); end; end; procedure TMainForm.LigarButtonClick(Sender: TObject); begin if ComPort.Connected then begin RSConnect:=false; RSSending:=False; Tools1.Enabled:=false; ComPort.Close; LigarButton.Caption:='Connect to FEUP X-10 PC Module'; StatusBar.Panels.Items[0].Text:='Not connected to FEUP X-10 PC Module'; UpdateDetails(GetModuleIndex); end else begin ComPort.Open;

TDI - Transdutores domóticos inteligentes

Relatório Final 228/276

// Envia comando de teste para estabelecer ligação ComPort.TransmitChar(chr(22)); //Inicio de transmissao ComPort.TransmitChar(chr(1)); ComPort.WriteStr('CONNECT'); ComPort.TransmitChar(chr(23)); Timer.Interval:=1000; // Time Out em 1 segs Timer.Enabled:=true; end; end; procedure TMainForm.Quit1Click(Sender: TObject); begin Close; end; procedure TMainForm.ComPortSettings1Click(Sender: TObject); begin ComPortSettings.Show; MainForm.Enabled:=False; end; procedure TMainForm.ModuleListBoxClick(Sender: TObject); begin UpdateDetails(GetModuleIndex); end; procedure TMainForm.TimerTimer(Sender: TObject); begin Timer.Enabled:=False; ShowMessage('Error: FEUP X-10 PC Module not found!'); RSConnect:=false; ComPort.Close; end; procedure TMainForm.ControlONButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, Module[GetModuleIndex].UC, X10ON, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end;

TDI - Transdutores domóticos inteligentes

Relatório Final 229/276

procedure TMainForm.ControlOFFButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, Module[GetModuleIndex].UC, X10OFF, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end; procedure TMainForm.ControlBRIGHTButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, 255, X10BRIGHT, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end; procedure TMainForm.ControlDIMButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, 255, X10DIM, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end; procedure TMainForm.PluggedButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, Module[GetModuleIndex].UC, X10HAILREQ, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end; procedure TMainForm.StatusButtonClick(Sender: TObject); begin SendToQueue(NO, Module[GetModuleIndex].HC, Module[GetModuleIndex].UC, X10STATUSREQ, 0); ActivateX10Send; ShowSendingWindow('Sending X-10 Command...', FALSE, 5, 'MainForm'); end; procedure TMainForm.SnifferMode1Click(Sender: TObject); begin SnifferForm.Visible:=true; SnifferForm.Enabled:=true; SnifferForm.BringToFront; end;

TDI - Transdutores domóticos inteligentes

Relatório Final 230/276

procedure TMainForm.FormCreate(Sender: TObject); var Reg: TRegistry; i : integer; begin ModulesIni := ExtractFilePath(Application.ExeName) + 'modules.ini'; Reg := TRegistry.Create; try reg.RootKey := HKEY_LOCAL_MACHINE; if reg.OpenKey('software\FEUP X10', False) then // Caso exista registo begin ModulesIni := reg.Readstring('ModulesIni'); end else // Caso nao exista registo begin if reg.OpenKey('software\FEUP X10', True) then begin Reg.WriteString('ModulesIni',ModulesIni); ComPort.StoreSettings(stRegistry, 'HKEY_LOCAL_MACHINE\Software\FEUP X10'); end; end; reg.CloseKey; finally Reg.Free; inherited; end; LoadModulesIni; UpdateModulesList; // SnifferForm.Visible:=false; // SnifferForm.Enabled:=false; ComPort.LoadSettings(stRegistry, 'HKEY_LOCAL_MACHINE\Software\FEUP X10'); StatusBar.Panels.Items[2].Text:=ComPort.Port; StatusBar.Panels.Items[1].Text:=ExtractFileName(ModulesIni); StatusBar.Panels.Items[0].Text:='Not connected to FEUP X-10 PC Module'; RSCount:=0;

TDI - Transdutores domóticos inteligentes

Relatório Final 231/276

for i:=1 to 255 do RSBuffer[i]:=chr(0); RSConnect:=FALSE; RSCommandRec := FALSE; RSInitCommandRec :=FALSE; RSSending:=FALSE; RSConfirmation :=0; for i:=0 to 9 do new(Queue[i]); queueSize := 0; queuePos := 0; ActiveModuleHC := #0; ActiveModuleUC := 0; end; procedure TMainForm.Add1Click(Sender: TObject); begin MainForm.Enabled:=False; AddModuleForm.Show; end; procedure TMainForm.Edit2Click(Sender: TObject); begin if ModuleListBox.ItemIndex = -1 then with Application do begin NormalizeTopMosts; MessageBox('Error: Select a module to edit!', 'Edit Module', MB_OK); RestoreTopMosts; end else begin MainForm.Enabled:=False; EditModuleForm.Show; end; end; procedure TMainForm.Delete1Click(Sender: TObject); var i : integer; begin

TDI - Transdutores domóticos inteligentes

Relatório Final 232/276

if ModuleListBox.ItemIndex = -1 then with Application do begin NormalizeTopMosts; MessageBox('Error: Select a module to delete!', 'Delete Module', MB_OK); RestoreTopMosts; end else begin with Application do begin NormalizeTopMosts; if MessageBox('Are you sure you want to delete '+ '' + '?', 'Delete Module' , MB_YESNO)= IDYES then begin module[GetModuleIndex].name:=''; UpdateModulesList; UpdateDetails(-1); end; // Por nome do modulo ver net RestoreTopMosts; end; end; end; procedure TMainForm.SetDefaultConfigClick(Sender: TObject); var Reg: TRegistry; i : integer; begin Reg := TRegistry.Create; try reg.RootKey := HKEY_LOCAL_MACHINE; if reg.OpenKey('software\FEUP X10', False) then // Caso exista registo begin Reg.WriteString('ModulesIni',ModulesIni);

TDI - Transdutores domóticos inteligentes

Relatório Final 233/276

Application.NormalizeTopMosts; Application.MessageBox('Configuration file changed sucessfully!', 'Configuration File', MB_OK); Application.RestoreTopMosts; end else begin Application.NormalizeTopMosts; Application.MessageBox('A error ocurred in registry operation!', 'Configuration File', MB_OK); Application.RestoreTopMosts; end; reg.CloseKey; finally Reg.Free; inherited; end; end; procedure TMainForm.About1Click(Sender: TObject); begin MainForm.Enabled:=False; AboutForm.Show; end; procedure TMainForm.OpenConfiguration1Click(Sender: TObject); begin if OpenDialog.Execute then begin ModulesIni := OpenDialog.FileName; StatusBar.Panels.Items[1].Text:=ExtractFileName(ModulesIni); LoadModulesIni; UpdateModulesList; UpdateDetails(-1); end; end; procedure TMainForm.Saveas1Click(Sender: TObject); begin SaveDialog.FileName:=ModulesIni; if SaveDialog.Execute then begin ModulesIni := SaveDialog.FileName; StatusBar.Panels.Items[1].Text:=ExtractFileName(ModulesIni); SaveModuleIni; end; end; procedure TMainForm.Save1Click(Sender: TObject);

TDI - Transdutores domóticos inteligentes

Relatório Final 234/276

begin SaveModuleIni; end; procedure TMainForm.ModSettingsButtonClick(Sender: TObject); begin ModuleSettingsForm.SerialEdit.Text:= inttostr(Module[GetModuleIndex].serialN); ModuleSettingsForm.GHCComboBox.ItemIndex:=ord(Module[GetModuleIndex].HC)-65; ModuleSettingsForm.GUCComboBox.ItemIndex:= Module[GetModuleIndex].UC -1; MainForm.Enabled:=False; ModuleSettingsForm.Show; end; procedure TMainForm.ScheduleButtonClick(Sender: TObject); begin MainForm.Enabled:=False; ScheduleSettingsForm.Show; end; end. unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, CPortCtl, Registry, CPort; type TComPortSettings = class(TForm) ComPortLabel: TLabel; SaveButton: TButton; CloseButton: TButton; ComComboBox: TComboBox; procedure CloseButtonClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure SaveButtonClick(Sender: TObject); procedure ComComboBoxChange(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations }

TDI - Transdutores domóticos inteligentes

Relatório Final 235/276

public { Public declarations } end; var ComPortSettings: TComPortSettings; implementation uses Unit1; {$R *.dfm} procedure TComPortSettings.CloseButtonClick(Sender: TObject); begin SaveButton.Enabled:=False; Close; end; procedure TComPortSettings.FormActivate(Sender: TObject); var reg: TRegistry; st: Tstrings; i: Integer; begin ComComboBox.Items.Clear; reg := TRegistry.Create; try reg.RootKey := HKEY_LOCAL_MACHINE; reg.OpenKey('hardware\devicemap\serialcomm', False); st := TstringList.Create; try reg.GetValueNames(st); for i := 0 to st.Count - 1 do ComComboBox.Items.Add(reg.Readstring(st.strings[i])); finally st.Free; end; reg.CloseKey; finally reg.Free; end; ComComboBox.ItemIndex:=0; end;

TDI - Transdutores domóticos inteligentes

Relatório Final 236/276

procedure TComPortSettings.SaveButtonClick(Sender: TObject); begin MainForm.ComPort.Port:=ComComboBox.Items.Strings[ComComboBox.ItemIndex]; MainForm.StatusBar.Panels.Items[2].Text:=MainForm.ComPort.Port; MainForm.ComPort.StoreSettings(stRegistry, 'HKEY_LOCAL_MACHINE\Software\FEUP X10'); ShowMessage('Settings saved! ' + ComComboBox.Items.Strings[ComComboBox.ItemIndex]); end; procedure TComPortSettings.ComComboBoxChange(Sender: TObject); begin SaveButton.Enabled:=True; end; procedure TComPortSettings.FormClose(Sender: TObject; var Action: TCloseAction); begin MainForm.Enabled:=True; MainForm.Visible:=True; end; end. unit Unit3; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TSnifferForm = class(TForm) SnifferListBox: TListBox; CloseButton: TButton; procedure CloseButtonClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var

TDI - Transdutores domóticos inteligentes

Relatório Final 237/276

SnifferForm: TSnifferForm; implementation {$R *.dfm} procedure TSnifferForm.CloseButtonClick(Sender: TObject); begin Close; end; end. unit Unit4; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TAddModuleForm = class(TForm) Label1: TLabel; NameEdit: TEdit; LampCheckBox: TCheckBox; GroupBox1: TGroupBox; IntelliFEUPRadioButton: TRadioButton; TwoWayRadioButton: TRadioButton; StandardRadioButton: TRadioButton; GroupBox2: TGroupBox; SensorRadioButton: TRadioButton; ActuatorRadioButton: TRadioButton; TimerCheckBox: TCheckBox; SaveButton: TButton; CancelButton: TButton; Label2: TLabel; TypeNameEdit: TEdit; SerialNLabel: TLabel; SerialNEdit: TEdit; Label4: TLabel; Label5: TLabel; HCComboBox: TComboBox; UCComboBox: TComboBox; procedure CancelButtonClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure SaveButtonClick(Sender: TObject);

TDI - Transdutores domóticos inteligentes

Relatório Final 238/276

procedure TwoWayRadioButtonClick(Sender: TObject); procedure IntelliFEUPRadioButtonClick(Sender: TObject); procedure StandardRadioButtonClick(Sender: TObject); procedure SensorRadioButtonClick(Sender: TObject); procedure ActuatorRadioButtonClick(Sender: TObject); procedure FormActivate(Sender: TObject); function CompareModName(name : string) : integer; private { Private declarations } public { Public declarations } end; var AddModuleForm: TAddModuleForm; implementation uses Unit1; {$R *.dfm} function TAddModuleForm.CompareModName(name : string) : integer; var ModCount : integer; begin ModCount := 0; while module[ModCount] <> NIL do begin if UpperCase(Module[ModCount].Name) = UpperCase(name) then begin CompareModName:=1; break; end else CompareModName:=0; inc(ModCount); end; end; procedure TAddModuleForm.CancelButtonClick(Sender: TObject); begin AddModuleForm.Close; end; procedure TAddModuleForm.FormClose(Sender: TObject;

TDI - Transdutores domóticos inteligentes

Relatório Final 239/276

var Action: TCloseAction); begin MainForm.Enabled:=True; end; procedure TAddModuleForm.SaveButtonClick(Sender: TObject); var ModCount : integer; begin if (NameEdit.Text='') or (TypeNameEdit.Text= '') or ((serialNEdit.Enabled = True) and (serialNEdit.Text = '')) then ShowMessage('Error: There are empty fields!') Else if ((serialNEdit.Enabled = True) and ((strtoint(serialNEdit.Text) = 0) or (strtoint(serialNEdit.Text) > 65535)) ) then ShowMessage('Error: Serial number range must be between 1 and 65535!') Else if CompareModName(NameEdit.Text) = 1 then with Application do begin NormalizeTopMosts; MessageBox('There is already a module with that name!', 'Add Module', MB_OK); RestoreTopMosts; end Else Begin ModCount := 0; while (module[ModCount] <> NIL) do begin if module[ModCount].name = '' then break; inc(ModCount); end; if module[ModCount] = NIL then new(Module[ModCount]); module[ModCount].name:=NameEdit.Text; module[ModCount].typeName:=TypeNameEdit.Text; if standardRadioButton.Checked = True then module[ModCount].modTypeA:=1 else if TwoWayRadioButton.Checked = True then module[ModCount].modTypeA:=2 else module[ModCount].modTypeA:=3; if SensorRadioButton.Checked = True then module[ModCount].modTypeB:=1 else module[ModCount].modTypeB:=2; module[ModCount].HC:=HCComboBox.Items[HCComboBox.ItemIndex][1];

TDI - Transdutores domóticos inteligentes

Relatório Final 240/276

module[ModCount].UC:=strtoint(UCComboBox.Items[UCComboBox.ItemIndex]); if LampCheckBox.Checked = True then module[ModCount].lampFunc:=1 else module[ModCount].lampFunc:=0; if TimerCheckBox.Checked = True then module[ModCount].timerFunc:=1 else module[ModCount].timerFunc:=0; if serialNEdit.Text = '' then module[ModCount].serialN:=0 else module[ModCount].serialN:=strtoint(serialNEdit.Text); module[ModCount].hail:=0; module[ModCount].status:=0; MainForm.UpdateModulesList; Close; End; End; procedure TAddModuleForm.TwoWayRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=False; serialNEdit.Text:=''; SerialNLabel.Enabled:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TAddModuleForm.IntelliFEUPRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=True; SerialNLabel.Enabled:= True; if ActuatorRadioButton.Checked = True then TimerCheckBox.Enabled:=True; end; procedure TAddModuleForm.StandardRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=False; serialNEdit.Text:=''; SerialNLabel.Enabled:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TAddModuleForm.SensorRadioButtonClick(Sender: TObject); begin LampCheckBox.Enabled:=False; LampCheckBox.Checked:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TAddModuleForm.ActuatorRadioButtonClick(Sender: TObject);

TDI - Transdutores domóticos inteligentes

Relatório Final 241/276

begin LampCheckBox.Enabled:=True; if intelliFEUPRadioButton.Checked = True then TimerCheckBox.Enabled:=True; end; procedure TAddModuleForm.FormActivate(Sender: TObject); begin NameEdit.Text:=''; TypeNameEdit.Text:=''; SerialNEdit.Text:=''; serialNEdit.Enabled:=False; LampCheckBox.Enabled:=False; SerialNLabel.Enabled:=False; TimerCheckBox.Enabled:=False; StandardRadioButton.Checked:=True; SensorRadioButton.Checked:=True; end; end. unit Unit5; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TAboutForm = class(TForm) Label1: TLabel; procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var AboutForm: TAboutForm; implementation uses Unit1; {$R *.dfm}

TDI - Transdutores domóticos inteligentes

Relatório Final 242/276

procedure TAboutForm.FormClose(Sender: TObject; var Action: TCloseAction); begin MainForm.Enabled:=True; end; end. unit Unit6; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TEditModuleForm = class(TForm) Label1: TLabel; Label2: TLabel; SerialNLabel: TLabel; Label4: TLabel; Label5: TLabel; NameEdit: TEdit; LampCheckBox: TCheckBox; GroupBox1: TGroupBox; IntelliFEUPRadioButton: TRadioButton; TwoWayRadioButton: TRadioButton; StandardRadioButton: TRadioButton; GroupBox2: TGroupBox; SensorRadioButton: TRadioButton; ActuatorRadioButton: TRadioButton; TimerCheckBox: TCheckBox; SaveButton: TButton; CancelButton: TButton; TypeNameEdit: TEdit; SerialNEdit: TEdit; HCComboBox: TComboBox; UCComboBox: TComboBox; procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure CancelButtonClick(Sender: TObject); procedure StandardRadioButtonClick(Sender: TObject); procedure TwoWayRadioButtonClick(Sender: TObject); procedure IntelliFEUPRadioButtonClick(Sender: TObject); procedure SensorRadioButtonClick(Sender: TObject);

TDI - Transdutores domóticos inteligentes

Relatório Final 243/276

procedure ActuatorRadioButtonClick(Sender: TObject); procedure SaveButtonClick(Sender: TObject); function CompareModName(name : string) : integer; private { Private declarations } public { Public declarations } end; var EditModuleForm: TEditModuleForm; implementation uses Unit1; {$R *.dfm} function TEditModuleForm.CompareModName(name : string) : integer; var ModCount : integer; begin ModCount := 0; while module[ModCount] <> NIL do begin if UpperCase(Module[ModCount].Name) = UpperCase(name) then begin CompareModName:=1; break; end else CompareModName:=0; inc(ModCount); end; end; procedure TEditModuleForm.FormActivate(Sender: TObject); var i : integer; begin i:=MainForm.GetModuleIndex; NameEdit.Text:=module[i].name; TypeNameEdit.Text:=module[i].typeName; LampCheckBox.Checked:=False; TimerCheckBox.Checked:=False;

TDI - Transdutores domóticos inteligentes

Relatório Final 244/276

SerialNEdit.Text:=''; if module[i].lampFunc = 1 then LampCheckBox.Checked:=True; if module[i].timerFunc = 1 then TimerCheckBox.Checked:=True; SerialNLabel.Enabled:=False; SerialNEdit.Enabled:=False; TimerCheckBox.Enabled:=False; LampCheckBox.Enabled:=False; if module[i].modTypeA=1 then begin StandardRadioButton.Checked:=True; End Else if module[i].modTypeA=2 then Begin TwoWayRadioButton.Checked:=True; End Else Begin intelliFEUPRadioButton.Checked:=True; SerialNLabel.Enabled:=True; SerialNEdit.Enabled:=True; SerialNEdit.Text:=inttostr(module[i].serialN); End; if module[i].modTypeB=1 then Begin SensorRadioButton.Checked:=True; End Else Begin ActuatorRadioButton.Checked:=True; LampCheckBox.Enabled:=True; if module[i].modTypeA=3 then TimerCheckBox.Enabled:=True; End; HCComboBox.ItemIndex:=ord(module[i].HC) - 65; UCComboBox.ItemIndex:=module[i].UC - 1; end; procedure TEditModuleForm.FormClose(Sender: TObject; var Action: TCloseAction); begin MainForm.Enabled:=True; end; procedure TEditModuleForm.CancelButtonClick(Sender: TObject); begin EditModuleForm.Close;

TDI - Transdutores domóticos inteligentes

Relatório Final 245/276

end; procedure TEditModuleForm.TwoWayRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=False; serialNEdit.Text:=''; SerialNLabel.Enabled:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TEditModuleForm.IntelliFEUPRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=True; SerialNLabel.Enabled:= True; if ActuatorRadioButton.Checked = True then TimerCheckBox.Enabled:=True; end; procedure TEditModuleForm.StandardRadioButtonClick(Sender: TObject); begin serialNEdit.Enabled:=False; serialNEdit.Text:=''; SerialNLabel.Enabled:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TEditModuleForm.SensorRadioButtonClick(Sender: TObject); begin LampCheckBox.Enabled:=False; LampCheckBox.Checked:=False; TimerCheckBox.Enabled:=False; TimerCheckBox.Checked:=False; end; procedure TEditModuleForm.ActuatorRadioButtonClick(Sender: TObject); begin LampCheckBox.Enabled:=True; if intelliFEUPRadioButton.Checked = True then TimerCheckBox.Enabled:=True; end; procedure TEditModuleForm.SaveButtonClick(Sender: TObject); var i : integer; begin i := MainForm.GetModuleIndex; if (NameEdit.Text='') or (TypeNameEdit.Text= '') or ((serialNEdit.Enabled = True) and (serialNEdit.Text = '')) then ShowMessage('Error: There are empty fields!') Else if ((serialNEdit.Enabled = True)

TDI - Transdutores domóticos inteligentes

Relatório Final 246/276

and ((strtoint(serialNEdit.Text) = 0) or (strtoint(serialNEdit.Text) > 65535)) ) then ShowMessage('Error: Serial number range must be between 1 and 65535!') Else if ( (UpperCase(NameEdit.Text) <> UpperCase(module[i].name)) and (CompareModName(NameEdit.Text) = 1)) then with Application do begin NormalizeTopMosts; MessageBox('There is already a module with that name!', 'Edit Module', MB_OK); RestoreTopMosts; end Else Begin module[i].name:=NameEdit.Text; module[i].typeName:=TypeNameEdit.Text; if standardRadioButton.Checked = True then module[i].modTypeA:=1 else if TwoWayRadioButton.Checked = True then module[i].modTypeA:=2 else module[i].modTypeA:=3; if SensorRadioButton.Checked = True then module[i].modTypeB:=1 else module[i].modTypeB:=2; module[i].HC:=HCComboBox.Items[HCComboBox.ItemIndex][1]; module[i].UC:=strtoint(UCComboBox.Items[UCComboBox.ItemIndex]); if LampCheckBox.Checked = True then module[i].lampFunc:=1 else module[i].lampFunc:=0; if TimerCheckBox.Checked = True then module[i].timerFunc:=1 else module[i].timerFunc:=0; if serialNEdit.Text = '' then module[i].serialN:=0 else module[i].serialN:=strtoint(serialNEdit.Text); MainForm.UpdateModulesList; MainForm.UpdateDetails(i); MainForm.ModuleListBox.ItemIndex:=i; Close; End; end; end. unit Unit7; interface

TDI - Transdutores domóticos inteligentes

Relatório Final 247/276

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TModuleSettingsForm = class(TForm) GroupBox1: TGroupBox; Label4: TLabel; SUCComboBox: TComboBox; SCommandComboBox: TComboBox; Update2Button: TButton; Label6: TLabel; Label7: TLabel; GroupBox2: TGroupBox; SerialEdit: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Update1Button: TButton; GUCComboBox: TComboBox; GHCComboBox: TComboBox; UpdateSerialButton: TButton; CloseButton: TButton; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Update2ButtonClick(Sender: TObject); procedure Update1ButtonClick(Sender: TObject); procedure CloseButtonClick(Sender: TObject); procedure UpdateSerialButtonClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormActivate(Sender: TObject); private { Private declarations } public { Public declarations } end; var ModuleSettingsForm: TModuleSettingsForm; implementation uses Unit1; {$R *.dfm} procedure TModuleSettingsForm.FormClose(Sender: TObject; var Action: TCloseAction); begin

TDI - Transdutores domóticos inteligentes

Relatório Final 248/276

MainForm.Enabled:=True; end; procedure TModuleSettingsForm.Update2ButtonClick(Sender: TObject); begin MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, (strtoint(SUCComboBox.Items[SUCComboBox.ItemIndex])*8) + (SCommandComboBox.ItemIndex + 1), X10EXTCONFSENSOR); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 5, 'ModuleSettingsForm'); end; procedure TModuleSettingsForm.Update1ButtonClick(Sender: TObject); begin MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, (GHCComboBox.ItemIndex*16 + GUCComboBox.ItemIndex), X10EXTCHANGEHUC); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 5, 'ModuleSettingsForm'); end; procedure TModuleSettingsForm.UpdateSerialButtonClick(Sender: TObject); begin MainForm.SendToQueue(YES, GHCComboBox.Items[GHCComboBox.ItemIndex][1], strtoint(GUCComboBox.Items[GUCComboBox.ItemIndex]), (Module[MainForm.GetModuleIndex].serialN and $00FF), X10EXTLSBSERIAL); MainForm.SendToQueue(YES, GHCComboBox.Items[GHCComboBox.ItemIndex][1], strtoint(GUCComboBox.Items[GUCComboBox.ItemIndex]), ((Module[MainForm.GetModuleIndex].serialN shr $8) and $00FF), X10EXTMSBSERIAL); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 5, 'ModuleSettingsForm'); end; procedure TModuleSettingsForm.CloseButtonClick(Sender: TObject); begin Close; end;

TDI - Transdutores domóticos inteligentes

Relatório Final 249/276

procedure TModuleSettingsForm.FormActivate(Sender: TObject); begin if (Module[MainForm.GetModuleIndex].modTypeB = 1) then begin SUCComboBox.Enabled:=True; SCommandComboBox.Enabled:=True; Update2Button.Enabled:=True; end else begin SUCComboBox.Enabled:=False; SCommandComboBox.Enabled:=False; Update2Button.Enabled:=False; end; end; end. unit Unit8; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TScheduleSettingsForm = class(TForm) ClearSchedulesButton: TButton; Button4: TButton; GroupBox1: TGroupBox; OptionComboBox: TComboBox; MonthComboBox: TComboBox; HourComboBox: TComboBox; DoWComboBox: TComboBox; CommandComboBox: TComboBox; DoMComboBox: TComboBox; MinComboBox: TComboBox; YearComboBox: TComboBox; SetScheduleButton: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel;

TDI - Transdutores domóticos inteligentes

Relatório Final 250/276

Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; GroupBox2: TGroupBox; UpdateTimeButton: TButton; Label10: TLabel; TimeLabel: TLabel; Timer1: TTimer; DateLabel: TLabel; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button4Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure UpdateTimeButtonClick(Sender: TObject); procedure ClearSchedulesButtonClick(Sender: TObject); procedure OptionComboBoxChange(Sender: TObject); procedure SetScheduleButtonClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var ScheduleSettingsForm: TScheduleSettingsForm; implementation uses Unit1; {$R *.dfm} procedure TScheduleSettingsForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Timer1.Enabled:=False; MainForm.Enabled:=True; end; procedure TScheduleSettingsForm.Button4Click(Sender: TObject); begin Close; end; procedure TScheduleSettingsForm.FormShow(Sender: TObject); begin

TDI - Transdutores domóticos inteligentes

Relatório Final 251/276

TimeLabel.caption:= TimeToStr(Time); DateLabel.caption:= DateToStr(Date); Timer1.Interval:=1000; Timer1.Enabled:=True; OptionComboBox.ItemIndex:=0; CommandComboBox.Enabled:=False; CommandComboBox.ItemIndex:=0; HourComboBox.Enabled:=False; HourComboBox.ItemIndex:=0; MinComboBox.Enabled:=False; MinComboBox.ItemIndex:=0; DoWComboBox.Enabled:=False; DoWComboBox.ItemIndex:=0; DoMComboBox.Enabled:=False; DoMComboBox.ItemIndex:=0; MonthComboBox.Enabled:=False; MonthComboBox.ItemIndex:=0; YearComboBox.Enabled:=False; YearComboBox.ItemIndex:=0; SetScheduleButton.Enabled:=False; end; procedure TScheduleSettingsForm.Timer1Timer(Sender: TObject); begin TimeLabel.caption:= TimeToStr(Time); DateLabel.caption:= DateToStr(Date); end; procedure TScheduleSettingsForm.UpdateTimeButtonClick(Sender: TObject); var Hour, Min, Sec, MSec, DofM, DofW, Year, YearCorrectFormat, Month : word; begin DecodeTime(Time, Hour, Min, Sec, MSec); DecodeDate(Date, Year, Month, DofM); DofW:=DayOfWeek(Date); YearCorrectFormat:= Year mod 1000; // Acerta relógio MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, 0, X10EXTSETCLOCK); // Ano MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, YearCorrectFormat, X10EXTSETYEAR); // Mes MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, Month, X10EXTSETMONTH); // Dia do Mes

TDI - Transdutores domóticos inteligentes

Relatório Final 252/276

MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, DofM, X10EXTSETDOM); // Dia da semana MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, DofW, X10EXTSETDOW); // Hora MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, Hour, X10EXTSETHOUR); // Minuto MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, Min, X10EXTSETMIN); // Segundos MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, SEC, X10EXTSETSEC); // END MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, 7, X10EXTSETEND); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 15, 'ScheduleSettingsForm'); end; procedure TScheduleSettingsForm.ClearSchedulesButtonClick(Sender: TObject); begin MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, $F0, X10EXTSCHOPTION); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 5, 'ScheduleSettingsForm'); end; procedure TScheduleSettingsForm.OptionComboBoxChange(Sender: TObject); begin // Todas as horas if OptionComboBox.ItemIndex = 1 then begin CommandComboBox.Enabled:=True; HourComboBox.Enabled:=False; MinComboBox.Enabled:=True; DoWComboBox.Enabled:=False; DoMComboBox.Enabled:=False; MonthComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // Todos os dias

TDI - Transdutores domóticos inteligentes

Relatório Final 253/276

else if OptionComboBox.ItemIndex = 2 then begin CommandComboBox.Enabled:=True; HourComboBox.Enabled:=True; MinComboBox.Enabled:=True; DoWComboBox.Enabled:=False; DoMComboBox.Enabled:=False; MonthComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // Todas as semanas else if OptionComboBox.ItemIndex = 3 then begin CommandComboBox.Enabled:=True; HourComboBox.Enabled:=True; MinComboBox.Enabled:=True; DoWComboBox.Enabled:=True; DoMComboBox.Enabled:=False; MonthComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // Todos os meses else if OptionComboBox.ItemIndex = 4 then begin CommandComboBox.Enabled:=True; HourComboBox.Enabled:=True; MinComboBox.Enabled:=True; DoMComboBox.Enabled:=True; DoWComboBox.Enabled:=False; MonthComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // Todos os anos else if OptionComboBox.ItemIndex = 5 then begin CommandComboBox.Enabled:=True; HourComboBox.Enabled:=True; MinComboBox.Enabled:=True; DoMComboBox.Enabled:=True; MonthComboBox.Enabled:=True; DoWComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // Pontualmente else if OptionComboBox.ItemIndex = 6 then begin CommandComboBox.Enabled:=True; CommandComboBox.Enabled:=True; HourComboBox.Enabled:=True; MinComboBox.Enabled:=True;

TDI - Transdutores domóticos inteligentes

Relatório Final 254/276

DoMComboBox.Enabled:=True; MonthComboBox.Enabled:=True; YearComboBox.Enabled:=True; DoWComboBox.Enabled:=False; SetScheduleButton.Enabled:=True; end // 3: else begin CommandComboBox.Enabled:=False; HourComboBox.Enabled:=False; MinComboBox.Enabled:=False; DoWComboBox.Enabled:=False; DoMComboBox.Enabled:=False; MonthComboBox.Enabled:=False; YearComboBox.Enabled:=False; SetScheduleButton.Enabled:=False; end; end; procedure TScheduleSettingsForm.SetScheduleButtonClick(Sender: TObject); var count : integer; begin count:= 0; // Opcao e comando MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, ((OptionComboBox.ItemIndex * 16) + (CommandComboBox.ItemIndex +1)), X10EXTSCHOPTION); // Minutos MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, MinComboBox.ItemIndex, X10EXTSETMIN); inc(count); if (OptionComboBox.ItemIndex <> 1) then begin // Hora MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, HourComboBox.ItemIndex, X10EXTSETHOUR); inc(count); end; if (OptionComboBox.ItemIndex = 3) then begin // Dia da semana

TDI - Transdutores domóticos inteligentes

Relatório Final 255/276

MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, DoWComboBox.ItemIndex, X10EXTSETDOW); inc(count); end; if ((OptionComboBox.ItemIndex = 4) or (OptionComboBox.ItemIndex = 5) or (OptionComboBox.ItemIndex = 6)) then begin // Dia do Mes MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, DoMComboBox.ItemIndex + 1 , X10EXTSETDOM); inc(count); end; if ((OptionComboBox.ItemIndex = 5) or (OptionComboBox.ItemIndex = 6)) then begin // Mes MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, MonthComboBox.ItemIndex + 1, X10EXTSETMONTH); inc(count); end; if (OptionComboBox.ItemIndex = 6) then begin // Ano MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, (strtoint(YearComboBox.Items[YearComboBox.ItemIndex]) mod 100), X10EXTSETYEAR); inc(count); end; // END MainForm.SendToQueue(YES, Module[MainForm.GetModuleIndex].HC, Module[MainForm.GetModuleIndex].UC, count, X10EXTSETEND); MainForm.ActivateX10Send; MainForm.ShowSendingWindow('Sending X-10 Command...', TRUE, 15, 'ScheduleSettingsForm'); end; end. unit Unit9;

TDI - Transdutores domóticos inteligentes

Relatório Final 256/276

interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls; type TSendingForm = class(TForm) Label1: TLabel; ProgressBar1: TProgressBar; Timer1: TTimer; Timer2: TTimer; Timer3: TTimer; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Timer1Timer(Sender: TObject); procedure Timer2Timer(Sender: TObject); procedure Timer3Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; var SendingForm: TSendingForm; TimerCounter : integer; implementation uses Unit1, Unit7, Unit8; {$R *.dfm} procedure TSendingForm.FormClose(Sender: TObject; var Action: TCloseAction); begin if SendingActiveForm = 'MainForm' then MainForm.Enabled:=True; if SendingActiveForm = 'ModuleSettingsForm' then ModuleSettingsForm.Enabled:=True; if SendingActiveForm = 'ScheduleSettingsForm' then ScheduleSettingsForm.Enabled:=True; end; procedure TSendingForm.Timer1Timer(Sender: TObject); begin if (RSSending = FALSE) then begin TimerCounter := 0; ProgressBar1.Position:=0;

TDI - Transdutores domóticos inteligentes

Relatório Final 257/276

Timer1.Enabled:=False; if RSConfirmation = 1 then begin label1.Caption:='Waiting for confirmation...'; TimerCounter := 0; ProgressBar1.Min:=0; ProgressBar1.Max:=10; ProgressBar1.Position:=0; Timer2.Interval:=100; Timer2.Enabled:=true; end else begin Timer3.Enabled:=False; SendingForm.Close; end; end else Begin ProgressBar1.Position:= ProgressBar1.Position + 1; if (TimerCounter = 10) then begin TimerCounter := 0; ProgressBar1.Min:=0; ProgressBar1.Max:=10; ProgressBar1.Position:=0; end else begin inc(TimerCounter); Timer1.Enabled:=true; end; end; end; procedure TSendingForm.Timer2Timer(Sender: TObject); begin if RSConfirmation = 2 then begin RSConfirmation := 0; TimerCounter := 0; ProgressBar1.Position:=0; Timer2.Enabled:=False; SendingForm.Close; Timer3.Enabled:=False; end else begin ProgressBar1.Position:= ProgressBar1.Position + 1; if (TimerCounter = 10) then begin TimerCounter := 0; ProgressBar1.Min:=0; ProgressBar1.Max:=10; ProgressBar1.Position:=0;

TDI - Transdutores domóticos inteligentes

Relatório Final 258/276

end else begin inc(TimerCounter); Timer2.Enabled:=true; end; end; end; procedure TSendingForm.Timer3Timer(Sender: TObject); begin Timer3.Enabled:=False; Timer2.Enabled:=False; Timer1.Enabled:=False; with Application do begin NormalizeTopMosts; MessageBox('ALTERT: Time out ocurred! Check connections or try to restart PC module!', 'Timeout', MB_OK); RestoreTopMosts; SendingForm.Close; end; end; end.

ANEXO E – ESQUEMAS E NEGATIVOS DAS PLACAS

Módulo “Interface para PC”

Face superior

Face inferior

R121k

C12 33nF

+5V

U5

4N25

1 6

2

5

4

C16 10pF

C2115nF

L1 47uH

Q3BC546

+26V

U4

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

+5V

C61000uF

Q2BD139

R1810K

C2310n

J2

RS232

123456789

10

+5V

D1

1N4004

Y17.68MHz

R8

33K

T11

2

43

65

220V

0V

0'V18'V

0''V18''V

Projecto TDi 0.1

FEUP PC Module

A2

1 1Monday , December 06, 2004

Title

Size Document Number Rev

Date: Sheet of

+5V

+26V

T2

P2821

1 6

5

3 4

U3

6N136

2

35

67

8

R13 2.2k

U2D

4069

9 8

147

C8

1nF

+5V

+5V

3 4

1 2

C2415p

D10

1N4148

U2A

4069

1 2

147

J1

220V

12

Q1BD138

+5V

R11

820

R5 220k

R16

47k

D2

1N4004C52200uF

C1810n

R9

1k

+26V

D31N4004

R6 47k

U2C

4069

5 6

147

C201.8nF

+5V

C17 10pF

C4

220nF

C2210n

U2B

4069

3 4

147

U6

4N25

16

2

5

4

+5V

C191.8nF

U7 DS2751

2

3

4

57

8

RXOUT

VDRV

TXIN

GN

D_P

C

TXOUTRXIN

alim

e

+5V

L2 47uH

D5

1N4148

R19

390

U2E

4069

11 10

147

F1

FUSE

C15

100pU8LM7805

1

2

3VI

GN

D

V0

R211k

D6 1N4148

D9 1N4148

+26V

R7100k

R21k

C13 4.7nF

R204k7

+5V

R10 1k

+5V

C10

150pF

R1120

R17100k

C7470uF

C3

220nF

R22 390

R310M

C2

150nF

C9

1uF D11 1N4148

D4

+5V

R14 820

D8 D1N4148

C2515p

+5V

C1

150nF

R158k2

U1LM7805

1

2

3VI

GN

D

VCC

C14 33nF

220V

C11 4.7nF

D71N4007

+5V

D1011V

R4470k

Módulo “Central de Inundação”

Face superior

Face inferior

R3518k

Q2BD139

U2B

4069

3 4

147

Q8

BC546

+5V

+5V

C11 4.7nF

Q6

BC546

SW1SW PUSHBUTTON-SPST-2

1 4

2 3

D911V

Projecto TDi 0.1

FEUP Flood Module

A2

1 1Friday , December 03, 2004

Title

Size Document Number Rev

Date: Sheet of

LED5

+5V

D71N4007

C52200uF

+5V

C2415p

R121k

LED6

C14 33nF

Y17.68MHz R24

6.8k

C1

150nF

C9

1uF

R28150k

U4

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

+5V

U2D

4069

9 8

147

J4

CON4

1234

R9

1k

R10 1k

C10

150pF

R17100k

+5V

J3

CON4

1234

C4

220nF

+26V

R1120

R5 220k

C291u

+5V

+5V

R38

10K

L2 47uH

J2

CON6

123456

U3

6N136

2

35

67

8

+5V

+5V

R33 56kC3

220nF

+5V

R23390

L1 47uH

Q3BC546

LED1

+26V

R34150k

C16 10pF

+5V

LS1

BUZZER

1

2

R19390

R21390

R13 2.2k

R25

10K

D6 1N4148

Q1BD138

D31N4004

D1

1N4004

C12 33nF

+5V+5V+5V

R4470k

D8 1N4148

+5V

+5V

C201.8nF

T2

P2821

1 6

5

3 4

R36 56k

C8

1nF

R30 56k

C61000uF

R6 47k

LED2

+5V

R14 820

J1

220V

12

+26V

J5

CON4

1234

C13 4.7nF

U1LM7805

1

2

3VI

GN

D

VCC

+5V

U2C

4069

5 6

147

C2515p

220V

Q7

BC546

+5V

C2210n

SW2

SW PUSHBUTTON-SPST

R158k2

LED3

R31150k

R3218k

R22390

R310M

C2310n

R8

33K

D2

1N4004

C281u

U2A

4069

1 2

147

R11

820

C2

150nF

U2E

4069

11 10

147

J6

CON4

1234

R20390

C7470uF

C261u

Q4

BC546

+5V

LED7

R2390

C17 10pF

F1

FUSE

R2918k

R27 56k

LED4

R18390

C191.8nF

D5

1N4148

+5V

+26V

C15

100p

R16

47k

T11

2

43

65

220V

0V

0'V18'V

0''V18''V

+5V +5V

C2115nF

D41N4148

Q5

BC546

+5V

R7100k

C271u

R37150k

R2618k

C1810n

Módulo “Sensor”

Face superior

Face inferior

+5V

R310M

+5V

J3

CON2

12

D8 1N4148

+5V

R9

1k

L2 47uH

C2210n

C1

150nF

R1120

+5V

R8

33K

R6 47k

U2A

4069

1 2

147

+5V

C4

220nF

+26V

R19

5k6

LED1

R17100k

R121k

R18

2k2

D5

1N4148

R4470k

+26V

C13 4.7nF

C52200uF

+5V

C16 10pF

Projecto TDi 0.1

Sensor Module

A2

1 1Tuesday , December 07, 2004

Title

Size Document Number Rev

Date: Sheet of

+5V

U3

6N136

2

35

67

8

F1

FUSE

D71N4007

C2

150nF

R14 820

+5V

L1 47uH

D2

1N4004

T2

P2821

1 6

5

3 4

U2E

4069

11 10

147

C201.8nF

+5V

220V

C2310n

R16

47k

D31N4004

U4

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

C15

100p

+5V

C3

220nF

C17 10pF

Q2BD139

+5V

Y17.68MHz

C8

1nF

SW1SW PUSHBUTTON-SPST-2

1 4

2 3

+5V

C1810n

C10

150pF

R158k2

Q1BD138

+26V

C2115nF

C11 4.7nF

+26V

C12 33nF

+5V

T11

2

43

65

220V

0V

0'V18'V

0''V18''V

C2415p

U2B

4069

3 4

147

C9

1uF

U2C

4069

5 6

147

C2515p

R5 220k

R13 2.2k

R2390

J2

CON6

123456

R38

10K

+5V

C7470uF

D1

1N4004

C191.8nF

D41N4148

R10 1kD911V

+5V

U1LM7805

1

2

3VI

GN

D

VCC

U2D

4069

9 8

147

C61000uF

R11

820

J1

220V

12

D6 1N4148

R7100k

+5V

U5

4N25

16

2

5

4

C14 33nF

Q3BC546

Módulo “Actuador AC”

Face superior

Face inferior

R2390

R121k C20

1.8nF

C2

150nF

L2 47uH

U3

6N136

2

35

67

8

U2A

4069

1 2

147

+5V

+5V

D911V

U5MOC3021

1

2

64

C10

150pF

C9

1uF

+26V

R23

470

L1 47uH R5 220k

R310M

C2310n

D41N4148

R13 2.2kR26

10K

D6 1N4148

Q1BD138

Projecto TDi 0.1

AC Actuator Module

A2

1 1Tuesday , December 07, 2004

Title

Size Document Number Rev

Date: Sheet of

J4 CON2

12

R21

47

LED1

LED2

SW2

SW PUSHBUTTON-SPST

C11 4.7nF

+5V

R16

47k

C8

1nF

R9

1k

R7100k

U4

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

Q4

BC546

+5V

U1LM7805

1

2

3VI

GN

D

VCC

C17 10pF

+5V

D2

1N4004

C14 33nF

LED3

C2710nF

SW1SW PUSHBUTTON-SPST-2

1 4

2 3

T11

2

43

65

220V

0V

0'V18'V

0''V18''V

R20

820

F1

FUSE

R25

10K

+5V

Q3BC546

C2415p

+26V

+5V

C191.8nF

R14 820

C1

150nF

+26V

C12 33nF

+5V

C15

100p

D8 1N4148

T2

P2821

1 6

5

3 4

R1120 C18

10n

U2D

4069

9 8

147

+5V

220V

U6

DS12C887

123456789

101112 13

1415161718192021222324

R18390

C61000uF

+5V

J2

CON6

123456

J1

220V

12

D1

1N4004

C16 10pF

R8

33K

+5V

R17100k

SW3

SW PUSHBUTTON-SPST

+5V

+5V

C2115nF

+5V

+5V

Q2BD139

R11

820

R24

39Q5BT139

R19390

U2B

4069

3 4

147

U2E

4069

11 10

147

D71N4007

R158k2

U2C

4069

5 6

147

C13 4.7nF

+5V

C7470uF

R4470k

C4

220nF

C2210n

D31N4004

R6 47k

D5

1N4148

+5V

C2610nF

C52200uF

C3

220nF

+5V

Y17.68MHz

J3 CON2

12

+26V

R10 1k

R22

390C2515p

R38

10K

+5V

+5V

Módulo “Actuador DC” Face superior

Face inferior

+5V

R121k

+5V

D71N4007

R6 47k

U3

6N136

2

35

67

8

+5V

+5V

J2

CON6

123456

C15

100p

Q2BD139

C9

1uF

D2

1N4004

C17 10pF

+5V

R18390

Projecto TDi 0.1

FEUP DC Actuator Module

A2

1 1Friday , December 10, 2004

Title

Size Document Number Rev

Date: Sheet of

Q5

BD139

U1LM7805

1

2

3VI

GN

D

VCC

R5 220k

C8

1nF

+5V

U2C

4069

5 6

147

+5V

+5V

R4470k

LED3

C13 4.7nF

D911V

R1120

R10 1k

R24

10K

C4

220nF

T11

2

43

65

220V

0V

0'V18'V

0''V18''V

U5

4N25

1 6

2

5

4

D8 1N4148

+5V

SW2

SW PUSHBUTTON-SPST

C2310n

C2210n

C12 33nF

C3

220nF

SW3

SW PUSHBUTTON-SPST

D6 1N4148

C14 33nF

+5V

Q3BC546

R16

47k

C52200uF

C1810n

R2310k

D5

1N4148

C2115nF

R13 2.2k

L2 47uH

Y17.68MHz

U2D

4069

9 8

147

R11

820

C61000uF

+26V

U6

DS12C887

123456789

101112 13

1415161718192021222324

Q1BD138

J1

220V

12

D10

1N4148

U4

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

R25

10K

C11 4.7nF

C2415p

L1 47uH

+5V

+5V

R2390

+5V

J3

CON4

1234

LED2

R26

10K

R19390

LED1

+26V

U2B

4069

3 4

147

+5V

+5V

F1

FUSE

R158k2

D1

1N4004

C2515p

R14 820

+5V

R22

1k5

R9

1k

D31N4004

+5V

R21

47

+26V

C16 10pF

C10

150pF

+5V

+5V

T2

P2821

1 6

5

3 4

D41N4148

U2A

4069

1 2

147

SW1SW PUSHBUTTON-SPST-2

1 4

2 3

C7470uF

+5V

C191.8nF

U2E

4069

11 10

147

R7100k

R310M

220V

R20

820

C1

150nF

C2

150nF

Q4

BC546

+26V

R17100k

D11

24V

C201.8nF

R8

33K

Programador para o microcontrolador PIC16F877A

Face superior

Face inferior

R6

10k

R21

10k

+5V

+12V

Q1

BC557C/PLP

+5V

D21N4004

U3

PIC16F877

123456789

1011121314151617181920

4039383736353433323130292827262524232221

+12V

U2LM7812C

1 3

2

IN OUT

GN

D

+5V

U4B

7407

34

147

R4

10k

+5V

U4E7407

11 10

147

T11

2

43

65

220V

0V

0'V6'V

0''V6''V

Vdd

R101k

+5V

R111k

Vdd

R7

10k

R8

10k

R310k

C3100n

+5V

LED2

U4C7407

56

147

FEUP 1

SCHAER PIC Programmer

A

1 1Friday , December 10, 2004

Title

Size Document Number Rev

Date: Sheet of

Vpp

+5V

R2

10k

R9

10k

+5V

J1

220V

12

D1 1N4004

+12V

Vdd

LED1

C2100n

R5

10k

U4D

7407

9 8

147

U4A7407

12

147

F1

FUSE

Vpp

Vdd

R1

10k

Vpp

J2

CON25

123456789

10111213141516171819202122232425

+5V

U1LM7805C

1 3

2

IN OUT

GN

D

Q2

BC557C/PLP

Vdd

U4F

7407

13 12

147

C11000uF