ROPE SIMULATOR RELATÓRIO FINALlaplima/ensino/pf/concluidos/1sem2008/ropes… · simulator) [7] 26...
Transcript of ROPE SIMULATOR RELATÓRIO FINALlaplima/ensino/pf/concluidos/1sem2008/ropes… · simulator) [7] 26...
Pontifícia Universidade Católica do Paraná Centro de Ciências Exatas e de Tecnologia
Engenharia de Computação
ROPE SIMULATOR RELATÓRIO FINAL
Alunos participantes: João Victor B. Gonçalves Thais Tucunduva Perim
______________________________________________ Professor Orientador: Lourival Lippmann
Primeiro Bimestre 2008
2
Índice
1. RESUMO 4
2. INTRODUÇÃO 5
3. PLANO DE TESTES 7
A. PROBLEMA 7 B. DIAGRAMA DE BLOCOS, TESTES E RESULTADOS ESPERADOS. 8
4. CRONOGRAMA 22
5. PROCEDIMENTOS DE TESTE E VALIDAÇÃO DE PROJETO 23
6. CONCLUSÃO 24
7. REFERÊNCIAS BIBLIOGRÁFICAS 25
ANEXO 1 (CÓDIGO DE COMUNICAÇÃO PIC/PC E IMPLEMENTAÇÃO DO ROPE SIMULATOR)[7] 26
ANEXO 2 (PROGRAMAS GRAVADOS NO PIC) 65
ANEXO 3 (PSEUDOCÓDIGO DO ROPE SIMULATOR) 76
ANEXO 4 – FOTOS 77
3
Índice de Figuras
Figura 1: Diagrama de Blocos Geral do Projeto...................................................................... 8
Figura 2: Diagrama de Blocos interno do sensor .................................................................... 9
Figura 3: GP1U783R[3]
.......................................................................................................... 9
Figura 4: Led infravermelho ................................................................................................... 9
Figura 5: Modulação do feixe de luz infravermelho.............................................................. 10
Figura 6: Circuito Integrado 556 – Multivibrador. [6]
............................................................ 10
Figura 7: Circuito do multivibrador (emissor) – dois componentes geras as freqüências de
833Hz e 32KHz respectivamente ......................................................................................... 11
Figura 8: Oscilador utilizando LM 556 ................................................................................. 11
Figura 9: Diagrama de blocos dos sensores .......................................................................... 12
Figura 10: PIC 16C745 ........................................................................................................ 13
Figura 11: Circuito de Comunicação .................................................................................... 14
Figura 12: Esboço da base (módulo dos sensores) ................................................................ 15
Figura 13: Layout da placa construída na estrutura física...................................................... 16
Figura 14: Esquema da placa construída para estrutura física ............................................... 16
Figura 15: Diagrama de blocos da interface gráfica .............................................................. 18
Figura 16: Esboço da interface visual ................................................................................... 19
Figura 17: Interface visual implementada e apresentada ....................................................... 20
Figura 18: Tela de “GAME OVER” ..................................................................................... 20
Índice de Fotos
Foto 1: Foto da base (módulo dos sensores) ......................................................................... 15
Foto 2: Módulo dos sensores ................................................................................................ 77
Foto 3: Marca – ROPE Simulator ......................................................................................... 77
Foto 4: Multivibrador + Receptor infravermelho .................................................................. 78
Foto 5: Estrutura física ......................................................................................................... 78
4
1. Resumo
Há muito tempo pular corda é uma das brincadeiras infantis mais praticadas.
Além de divertido para todas as crianças é um ótimo exercício aeróbico, sendo
assim, a prática tem sido adotada até como exercício físico e treino por muitas
pessoas, principalmente, devido a grande queima de calorias e melhora do
condicionamento cardiorespiratório. É uma prática barata, eficaz e os resultados
aparecem em pouquíssimo tempo. [4]
Para pular corda é necessário ter espaço e ainda assim existem alguns fatores
que impedem a prática dessa atividade, tais como: ambiente com muita gente;
aparece o risco de ferimentos em outras pessoas enquanto a corda gira; ambiente
com obstáculos; na maioria das vezes se uma pessoa quer, por algum motivo, pular
corda dentro de casa, o risco de quebrar objetos (televisão, porta-retratos entre
outros objetos da casa) e se ferir a impedirão de realizar a tarefa.
O dispositivo que será desenvolvido tem a finalidade de entretenimento infantil
e juvenil e para fins de práticas de atividades esportivas. O fato de esse dispositivo
ser eletrônico, ou seja, uma simulação da brincadeira da corda; evita o ferimento de
outras pessoas e os possíveis danos a outros objetos que estiverem nas
proximidades do equipamento, além de abrir várias opções de competição, contar
quantos pulos a pessoa executou, marcar pontos, tempo e outros.
5
2. Introdução
O Centro de Pesquisa de Atividade Física da Universidade de Illinois testou em
grupo de atletas como a atividade de pular corda influenciaria no físico dessas
pessoas. Pulando 60 minutos por dia, durante cinco dias na semana, notou-se que
esses atletas tiveram uma melhora de condicionamento físico, agilidade e
flexibilidade, bem como velocidade em corridas e pernas e joelhos mais fortes e
panturrilha maior. A baixa intensidade no impacto também previne a osteoporose.
Miguel de Oliveira, 56 anos, ex-campeão mundial de boxe na categoria médio-
ligeiro, professor de educação física, pula corda há 40 anos e destaca os benefícios
da atividade.
“Pular corda é excelente para o condicionamento cardiovascular e para a
coordenação. E pode ser usado especificamente para o condicionamento para a
corrida, já que melhora a elevação do joelho e a volta da passada, por exemplo. Se
for feito corretamente, não há impacto nem risco de lesões. A coordenação motora e
respiratória desenvolvida pela corda é útil em todos os esportes.”, diz Miguel.
De acordo com uma pesquisa realizada pelo Centro de Vigilância
Epidemiológica da Secretaria Estadual da Saúde de São Paulo quase 40% dos
óbitos de crianças de 1 a 14 anos ocorrem devido a acidentes que poderiam ser
evitados. O levantamento aponta que os riscos podem estar dentro de casa, nos
mínimos detalhes, que podem acarretar em queda que, em 2005, foram
responsáveis por 74,6% das internações.
“A atenção dos pais e responsáveis é primordial quando o assunto é evitar que
as crianças e jovens se machuquem. É preciso pensar a casa como um local onde
tudo pode acontecer e, diante disso, tentar se antecipar aos possíveis riscos.”,
afirma Ricardo Tardelli, diretor estadual de Saúde. [1]
Pular corda é uma atividade divertida e bastante praticada pelas crianças, mas
proporciona riscos, quedas ou ferimentos proporcionados pela própria corda nas
crianças que praticam a atividade ou em terceiros e também danos a objetos.
Neste documento está descrito como o Rope Simulator, o simulador de corda,
será desenvolvido, ou seja, a descrição funcional do plano de projeto apresentado,
diagramas de bloco, projeto da interface visual do equipamento, bem como as
tecnologias selecionadas, pontos fortes e fracos e motivo da escolha de cada
6
tecnologia, os procedimentos de testes e validação do projeto, analise de risco de
desenvolvimento e implementação e o cronograma atualizado.
7
3. Plano de testes
a. Problema
A corda é um instrumento muito barato, mas possui uma série de limitações
para a prática da atividade de pular corda.
Nas academias o maior problema é a falta de espaço, muitas pessoas tendo
que dividir espaço com muitos equipamentos de ginástica, o que impossibilita a
prática individualmente ou em grupo.
No caso de uso para recreação infantil, é necessário que a criança esteja em
um ambiente amplo, sem obstáculos e sem movimento intenso de pessoas, para
evitar batidas na própria criança ou em terceiros ou o impacto com outros objetos
que sejam cortantes e que ofereceriam o risco de alguma pessoa tropeçar na corda
ocasionando alguma lesão, para esses é recomendável um ambiente externo a
casa, o que na maioria das vezes não é permitido por pais ou responsáveis devido a
outros riscos como atropelamento, riscos a saúde (gripe, pneumonia e outros
dependendo das condições climáticas) e outros problemas. Algumas brincadeiras de
pular corda requerem um grupo de crianças e algumas vezes elas não dispõem de
companhia tendo que executar a atividade individualmente o que, em alguns
momentos não seja possível de executar ou não proporciona a mesma diversão.
Não só crianças e jovens precisam executar atividades físicas, para todas as
pessoas o exercício aeróbico é muito importante e eficaz para manter e melhorar a
saúde de modo geral. O exercício aeróbico é caracterizado pelo esforço físico de
alta intensidade, que elevam os batimentos cardíacos, aumentando a oxigenação
das células, e aumentam o metabolismo, isso faz com que o corpo queime gorduras
e muita caloria. Andar, correr, pedalar, remar, dançar, subir escadas são alguns
exemplos de atividades aeróbicas, para esses tipos de exercício já existem
equipamentos eletrônicos e mecânicos capazes de simular o movimento realizado
pela atividade, agora o objetivo do desenvolvimento desse dispositivo é incorporar
mais um equipamento dentro das academias, das casas de jogos ou até em
ambientes residenciais para aprimorar e aumentar as opções para atividade
aeróbica dos atletas e das pessoas, sem sair de casa ou sem sair dos ambientes
que costumam freqüentar, já que algumas vezes não possuem espaço ou tempo
para a prática atividade aeróbica individual ou em conjunto que tem sido realizada
pelas pessoas cada vez com mais freqüência. [5]
8
O Rope Simulator oferecerá a possibilidade de atividade indoor, ou seja,
atividade que poderá ser praticada em um ambiente fechado, evitando os riscos
externos que foram citados anteriormente simulando uma corda. Mesmo podendo
ser comparado ao vídeo-game, o Rope Simulator garante atividade física da criança,
do jovem e do atleta já que o usuário pratica uma atividade aeróbica para poder
utilizar o equipamento.
O objetivo do Rope Simulator é criar mais uma solução para equipamentos de
recreação e atividades aeróbicas mais barato do que os existentes no mercado e de
fácil utilização e transporte além de ser uma ótima opção de treinamento para quem
não tem tempo de sair para correr ou executar outra atividade física. A seguir
apresentamos o diagrama de blocos geral e detalhado do projeto.
b. Diagrama de Blocos, testes e resultados esperados.
O projeto compõe basicamente de três módulos: módulo de interface gráfica,
módulo dos sensores e módulo de comunicação.
Módulo de
Interface Gráfica
Módulo de
Comunicação
Módulo dos
Sensores
Figura 1: Diagrama de Blocos Geral do Projeto
A seguir, cada módulo será detalhadamente explorado:
• Módulo dos sensores:
O módulo dos sensores conta com o emissor e receptor infravermelho. A lógica
é, após certo período de tempo em estado de espera (sem executar nenhuma
verificação dos sensores) os receptores são testados como mostra o diagrama da
figura 9 (abaixo).
Os sensores infravermelhos funcionarão com os seguintes equipamentos:
� Receptores do tipo GP1U783Q, uma unidade que detecta sinais
infravermelhos (como os de controle remoto) pouco sensíveis a ruídos externos, pois
funciona recebendo apenas um sinal modulado com a freqüência em que trabalha,
9
qualquer outro sinal é rejeitado. Esse equipamento é da fabricante SHARP. Ele
recebe um sinal infravermelho, amplifica, filtra, demodula e compara, gerando um
sinal binário na saída. O circuito interno do componente é mostrado na Figura 2.
Figura 2: Diagrama de Blocos interno do sensor
Figura 3: GP1U783R[3]
� Transmissores infravermelhos:
Esse dispositivo transmite um feixe de luz infravermelho que não é visível a
olho nu, com um comprimento de onda de 900nm. [2]
Figura 4: Led infravermelho
10
Para que esse dispositivo como um todo funcione, ou seja, para que o
GP1U783Q responda à algum sinal infravermelho recebido, o feixe de luz deve ser
modulado da seguinte maneira:
Figura 5: Modulação do feixe de luz infravermelho
Durante 600µs o feixe está sendo transmitido e durante 600µs não. Para que
isso seja possível um multivibrador poderá ser utilizado para gerar as duas
freqüências necessárias. Para que o sinal fique de acordo com a Figura 5, um
multivibrador fará o oscilador de 833 Hz (período de transmissão 1200µs) e outro de
32.75KHz (especificação do datasheet do receptor).
� Multivibrador:
Para gerar as freqüências acima para transmitir o feixe de luz infravermelha
será utilizado um chip de circuito integrado 556, que são dois componentes LM 555
dentro de um chip.
Figura 6: Circuito Integrado 556 – Multivibrador. [6]
Para realizar os primeiros testes e gerar as duas freqüências, o circuito básico
foi construído utilizando dois componentes LM 555 configurados nas freqüências
desejadas, como mostra a Figura 7.
11
Figura 7: Circuito do multivibrador (emissor) – dois componentes geras as freqüências de 833Hz e 32KHz
respectivamente
Para ficar mais compacto o circuito pode ser montado com o LM 556. Com
esse componente o circuito fica como mostra na Figura 8.
Figura 8: Oscilador utilizando LM 556
12
Sensores desligados
Teste do sensor X
X=1
Sensor X
detecta
presença?
Não
X>Nº de
Sensores?
Sim
Desliga o
equipamento
(usuário pisou na
corda)
Tempo
padrão
esgotado?
Sim
Não
Sim
Desliga sensor X
Liga sensor X+1
X=X+1
Não
Figura 9: Diagrama de blocos dos sensores
Resultado esperado do módulo de sensores
A funcionalidade básica do sensor está de acordo com o projeto, ou seja, o
LED infravermelho emite um sinal modulado que se captado pelo sensor, o mesmo
exibe nível lógico “0” na saída, caso exista um obstáculo entre emissor e receptor, a
saída do sensor fica em nível lógico “1”.
A vantagem de o sinal ser emitido de forma modulada, é que o circuito fica
bastante imune a ruídos.
13
A distância mínima entre os sensores deve ser de aproximadamente 20 cm e
para o projeto a distância máxima deve ser aproximadamente 60 cm, mesmo que o
sensor funcione a uma distância maior.
� PIC16C745-I/SP
Esse microcontrolador foi escolhido, pois tem embarcado uma interface USB
para ser implementada, ou seja, a comunicação do PIC – USB – Cabo –
Computador é facilitada por tudo estar implementado dentro de um único
componente. Esse PIC tem 28 portas de entradas e saídas analógicas, conversor
A/D, saída USB e é OTP (One Time Programing - Programável apenas uma vez). Do
fabricante Microchip pode ser programado usando o aplicativo MPLAB IDE e
gravado com o PICSTART PLUS que estão disponíveis na PUC-PR.
Figura 10: PIC 16C745
O circuito da figura a seguir foi construído a fim de testar a comunicação do
PIC com o PC via USB.
14
Figura 11: Circuito de Comunicação
Resultado esperado do módulo de comunicação
O primeiro resultado esperado para o PIC é a comunicação com o computador
via USB. O PC foi capaz de reconhecer o dispositivo, com isso é possível que exista
a comunicação entre PC e PIC. Esse teste foi considerado satisfatório já que o PC
reconhece o dispositivo com HID (Human Interface Device), inclusive é capaz de
identificar o modelo do PIC (modelo 16C745).
Com o código implementado (ver Anexo 1 e 2), o PIC foi capaz de receber e
interpretar o comando “?” e enviar para o PC o nível lógico dos pinos da porta A.
Com todos os dispositivos acima, construímos a base do equipamento. O
módulo dos sensores deve ficar semelhante ao esboço já apresentado no Plano de
Projeto.
15
Figura 12: Esboço da base (módulo dos sensores)
Foto 1: Foto da base (módulo dos sensores)
16
Figura 13: Layout da placa construída na estrutura física
Figura 14: Esquema da placa construída para estrutura física
17
• Módulo da interface gráfica:
A interface gráfica é responsável pela lógica do programa. Ela exibe na tela o
movimento da corda, acendendo e apagando “lâmpadas” no monitor, ao mesmo
tempo em que o bloco dos sensores trabalha e envia para o PIC o comando “?”
quando deve testar o estados dos sensores.
Se o sensor testado estiver em nível lógico “0” o jogo é interrompido e o status
do jogo é exibido, ou seja, uma tela de “GAME OVER” é colocada da tela.
Para testar se o jogador está na área dos sensores, o programa faz um teste
dos sensores quando a corda está posicionada na parte de cima do monitor. Nesse
caso, o jogo espera que exista um obstáculo interrompendo o sinal infravermelho, ou
seja, que exista uma pessoa na área dos sensores. Caso a afirmativa anterior não
seja verdadeira, a mesma mensagem de “GAME OVER” é exibida na tela.
A interface gráfica foi desenvolvida em Open GL.
18
Liga lâmpada X
Desliga lâmpada X
Liga lâmpada X+1
X>Nº de
Lâmpadas?
Exibe status na tela e
pontuação
Pára o programa
(usuário pisou na
corda)
Recebe comando
do módulo dos
sensores para
parar?Sim
Não
Recebe comando
Start do módulo dos
sensores
X=1
X=1
Recebe comando
do módulo dos
sensores para
parar?
Sim
Não
Sim Não
Figura 15: Diagrama de blocos da interface gráfica
19
A interface gráfica do projeto, depois de implementada deve ficar similar ao
esboço já apresentado no Plano de Projeto.
Figura 16: Esboço da interface visual
20
Figura 17: Interface visual implementada e apresentada
Figura 18: Tela de “GAME OVER”
21
Resultado esperado do módulo de interface gráfica
Na interface visual o usuário deve conseguir visualizar a corda e o desenho da
corda está sincronizado com o módulo dos sensores.
Com isso, o projeto já está trabalhando apropriadamente, as funcionalidades
básicas do Rope Simulator já estão implementadas e a corda girando já pode ser
simulada, mas uma única regra foi implementada, o usuário não tem opção de
seleção de nível, mas o movimento começa com uma velocidade baixa e aumenta
com o passar do tempo.
22
4. Cronograma
23
5. Procedimentos de teste e validação de projeto
Os procedimentos de testes e validação foram feitos para cada módulo
separado em primeira instância e depois para o conjunto todo.
Os sensores detectam a presença do usuário. A corda dispõe de um tempo
para dar um giro de 360º que depende da velocidade de giro. Então de tempos em
tempos os sensores devem ser ativados. Essa ativação é testada analisando o nível
de tensão nos terminais do receptor. Após a validação da ativação, o teste foi feito
para verificar se eles são aptos a detectar a presença de um material no tempo em
que estiverem ativados, para isso o nível de tensão também deve ser analisado.
O módulo de comunicação foi testado com a interface dos sensores
principalmente o componente PIC16C745-I/SP. Usando comunicação USB,
enviamos informação que devem ser exibidas da interface visual ou que deve alterar
alguma configuração. Como resultado, teremos atualizações no PC. Integrando a
comunicação com a interface visual, teremos atualizações no monitor do usuário.
O teste da interface de visualização foi visual. Sem qualquer interação com o
módulo de comunicação ou dos sensores o usuário foi capaz de ver uma simulação
do giro da corda, ou seja, o usuário teve a sensação de que tem uma corda girando.
Assim como o módulo dos sensores terá ligação com o módulo de
comunicação, a interface visual também deve estar. O microprocessador deve
receber e enviar informações da e para a interface visual, para manter sincronismo e
a lógica do jogo.
Após isso todos os módulos foram aptos a conversar entre si. O resultado
obtido foi satisfatório já que a regra principal do jogo está implementada. Agora é só
jogar e se divertir!
24
6. Conclusão
O Rope Simulator é um equipamento de simulação de corda. Foi desenvolvido
para suprir a necessidade de crianças e adultos em atividades recreativas e
atividades aeróbicas, para melhorar a qualidade de vida e aumentar as opções das
pessoas para desenvolver alguma tarefa. O intuito da construção desse dispositivo é
disponibilizar um exemplar do produto que tem a característica de ser mais barato e
que seja utilizado usando ferramentas comumente usadas pela população
(instrumentos de fácil acesso).
Neste documento pudemos apresentar as tecnologias que foram usadas na
construção do equipamento, os resultados finais obtidos e apresentados para os
orientadores de projeto final para conclusão do curso de Engenharia de
Computação, os módulos e diagramas de blocos (lógica de cada módulo),
equipamentos usados e códigos de implementação e fotos do projeto já
implementado e pronto para jogar!
25
7. Referências Bibliográficas
[1] Secretaria Estadual da Saúde, Acidentes causam 40% das mortes de crianças em
SP. Disponível em:
http://www.saopaulo.sp.gov.br/sis/lenoticia.php?id=87293&c=557&siteID=1.
Acessado em: 12 set 2007.
[2] AESPA. Sensores infravermelhos passivos e ativos. Disponível em:
http://www.aespa.com.br/infrared.htm. Acessado em 24 set 2007.
[3] Imagem. Receptor infravermelho GP1U783R da SHARP. Lynxmotion, Inc.
2007. Disponível em: http://www.lynxmotion.com/images/Products/Full/comp01.jpg.
Acessado em: 27 nov 2007.
[4] Wikipedia. Ginástica Aeróbica. Disponível em:
http://pt.wikipedia.org/wiki/Aer%C3%B3bica. Acessado em 13 set 2007
[5] Wikipedia. Ginástica Aeróbica. Disponível em:
http://pt.wikipedia.org/wiki/Gin%C3%A1stica_aer%C3%B3bica. Acessado em 13 set
2007.
[6] Imagem. Circuito Integrado 556, timer para construção do oscilador.
Disponível em: http://www.soldafria.com.br/loja/images/DIP_14PINOS.JPG.
Acessado em 08 abr 2008.
[7] The HID Page.. Resources for Developers of USB Devices in the
Human Interface Device Class. Visual Basic .NET, HIDClass for Visual Studio 2005.
Disponível em: http://www.lvr.com/hidpage.htm. Acessado em 12 abr 2008.
26
ANEXO 1 (código de comunicação PIC/PC e implementação do ROPE Simulator)[7]
USBhid.h extern "C" {
// This file is in the Windows DDK available from Microsoft.
#include "hidsdi.h"
#include <setupapi.h>
}
class CUsbhidiocDlg
{
private:
//Application global variables
HANDLE hDevInfo;
HANDLE ReadHandle;
HANDLE DeviceHandle;
HANDLE WriteHandle;
DWORD ActualBytesRead;
DWORD BytesRead;
HIDP_CAPS Capabilities;
DWORD cbBytesRead;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
DWORD dwError;
GUID HidGuid;
OVERLAPPED HIDOverlapped;
char InputReport[9];
ULONG Length;
LPOVERLAPPED lpOverLap;
bool MyDeviceDetected;
CString
MyDevicePathName;
DWORD NumberOfBytesRead;
char OutputReport[9];
DWORD ReportType;
ULONG Required;
CString ValueToDisplay;
int VendorID;
int ProductID;
public:
CUsbhidiocDlg(int vID, int pID);
bool Connect();
void Disconnect();
bool Receive(char *msgin);
bool Send(const char *msg);
protected:
void GetDeviceCapabilities();
void PrepareForOverlappedTransfer();
};
27
USBhid.cpp – versão 1.0
• Este arquivo foi o primeiro código utilizado para testar a comunicação do PIC com o PC, como descrito, enviando um sinal de “?” e devolvendo o status da porta A, sendo assim retornando o status dos sensores.
// usbhid.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "usbhid.h"
CUsbhidiocDlg::CUsbhidiocDlg(int vID, int pID)
{
VendorID = vID;
ProductID = pID;
MyDeviceDetected = false;
}
//Global Variables
HANDLE hEventObject;
void CUsbhidiocDlg::Disconnect()
{
//Close open handles.
if (DeviceHandle != INVALID_HANDLE_VALUE)
CloseHandle(DeviceHandle);
if (ReadHandle != INVALID_HANDLE_VALUE)
CloseHandle(ReadHandle);
if (WriteHandle != INVALID_HANDLE_VALUE)
CloseHandle(WriteHandle);
}
bool CUsbhidiocDlg::Connect()
{
//Use a series of API calls to find a HID with a specified Vendor IF
and Product ID.
HIDD_ATTRIBUTES Attributes;
SP_DEVICE_INTERFACE_DATA devInfoData;
bool LastDevice = FALSE;
int MemberIndex = 0;
LONG Result;
CString
UsageDescription;
Length = 0;
detailData = NULL;
DeviceHandle=NULL;
/*API function: HidD_GetHidGuid
Get the GUID for all system HIDs.
Returns: the GUID in HidGuid.*/
HidD_GetHidGuid(&HidGuid);
/*API function: SetupDiGetClassDevs
Returns: a handle to a device information set for all installed
devices.
Requires: the GUID returned by GetHidGuid.*/
hDevInfo=SetupDiGetClassDevs
(&HidGuid,
NULL,
NULL,
28
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
devInfoData.cbSize = sizeof(devInfoData);
//Step through the available devices looking for the one we want.
//Quit on detecting the desired device or checking all available
devices without success.
MemberIndex = 0;
LastDevice = FALSE;
do
{
/*API function: SetupDiEnumDeviceInterfaces
On return, MyDeviceInterfaceData contains the handle to a
SP_DEVICE_INTERFACE_DATA structure for a detected device.
Requires:
The DeviceInfoSet returned in SetupDiGetClassDevs.
The HidGuid returned in GetHidGuid.
An index to specify a device.*/
Result=SetupDiEnumDeviceInterfaces
(hDevInfo,
0,
&HidGuid,
MemberIndex,
&devInfoData);
if (Result != 0)
{
//A device has been detected, so get more information
about it.
/*API function: SetupDiGetDeviceInterfaceDetail
Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
containing information about a device.
To retrieve the information, call this function twice.
The first time returns the size of the structure in
Length.
The second time returns a pointer to the data in
DeviceInfoSet.
Requires:
A DeviceInfoSet returned by SetupDiGetClassDevs
The SP_DEVICE_INTERFACE_DATA structure returned by
SetupDiEnumDeviceInterfaces.
The final parameter is an optional pointer to an
SP_DEV_INFO_DATA structure.
This application doesn't retrieve or use the structure.
If retrieving the structure, set
MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
and pass the structure's address.*/
//Get the Length value.
//The call will return with a "buffer too small" error
which can be ignored.
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
NULL,
0,
&Length,
NULL);
29
//Allocate memory for the hDevInfo structure, using the
returned Length.
detailData =
(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
//Set cbSize in the detailData structure.
detailData -> cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
//Call the function again, this time passing it the
returned buffer size.
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
detailData,
Length,
&Required,
NULL);
// Open a handle to the device.
// To enable retrieving information about a system mouse
or keyboard,
// don't request Read or Write access for this handle.
/* API function: CreateFile
Returns: a handle that enables reading and writing to the
device.
Requires:
The DevicePath in the detailData structure
returned by SetupDiGetDeviceInterfaceDetail.*/
DeviceHandle=CreateFile
(detailData->DevicePath,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
/*API function: HidD_GetAttributes
Requests information from the device.
Requires: the handle returned by CreateFile.
Returns: a HIDD_ATTRIBUTES structure containing
the Vendor ID, Product ID, and Product Version Number.
Use this information to decide if the detected device is
the one we're looking for.*/
//Set the Size to the number of bytes in the structure.
Attributes.Size = sizeof(Attributes);
Result = HidD_GetAttributes
(DeviceHandle,
&Attributes);
//Is it the desired device?
MyDeviceDetected = FALSE;
if (Attributes.VendorID == VendorID)
{
if (Attributes.ProductID == ProductID)
30
{
//Both the Vendor ID and Product ID match.
MyDeviceDetected = TRUE;
MyDevicePathName = detailData->DevicePath;
//Get the device's capablities.
GetDeviceCapabilities();
// Get a handle for writing Output reports.
WriteHandle=CreateFile
(detailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
// Prepare to read reports using Overlapped
I/O.
PrepareForOverlappedTransfer();
} //if (Attributes.ProductID == ProductID)
else
//The Product ID doesn't match.
CloseHandle(DeviceHandle);
} //if (Attributes.VendorID == VendorID)
else
//The Vendor ID doesn't match.
CloseHandle(DeviceHandle);
//Free the memory used by the detailData structure (no
longer needed).
free(detailData);
} //if (Result != 0)
else
//SetupDiEnumDeviceInterfaces returned 0, so there are no
more devices to check.
LastDevice=TRUE;
//If we haven't found the device yet, and haven't tried every
available device,
//try the next one.
MemberIndex = MemberIndex + 1;
} //do
while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
//Free the memory reserved for hDevInfo by SetupDiClassDevs.
SetupDiDestroyDeviceInfoList(hDevInfo);
return MyDeviceDetected;
}
void CUsbhidiocDlg::GetDeviceCapabilities()
{
//Get the Capabilities structure for the device.
PHIDP_PREPARSED_DATA PreparsedData;
31
/*API function: HidD_GetPreparsedData
Returns: a pointer to a buffer containing the information about the
device's capabilities.
Requires: A handle returned by CreateFile.
There's no need to access the buffer directly,
but HidP_GetCaps and other API functions require a pointer to the
buffer.*/
HidD_GetPreparsedData
(DeviceHandle,
&PreparsedData);
/*API function: HidP_GetCaps
Learn the device's capabilities.
For standard devices such as joysticks, you can find out the specific
capabilities of the device.
For a custom device, the software will probably know what the device
is capable of,
and the call only verifies the information.
Requires: the pointer to the buffer returned by
HidD_GetPreparsedData.
Returns: a Capabilities structure containing the information.*/
HidP_GetCaps
(PreparsedData,
&Capabilities);
//No need for PreparsedData any more, so free the memory it's using.
HidD_FreePreparsedData(PreparsedData);
}
void CUsbhidiocDlg::PrepareForOverlappedTransfer()
{
//Get a handle to the device for the overlapped ReadFiles.
ReadHandle=CreateFile
(detailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
//Get an event object for the overlapped structure.
/*API function: CreateEvent Requires:
Security attributes or Null
Manual reset (true). Use ResetEvent to set the event object's state
to non-signaled.
Initial state (true = signaled)
Event object name (optional)
Returns: a handle to the event object*/
if (hEventObject == 0)
{
hEventObject = CreateEvent
(NULL,
TRUE,
TRUE,
LPCWSTR(""));
//Set the members of the overlapped structure.
HIDOverlapped.hEvent = hEventObject;
HIDOverlapped.Offset = 0;
32
HIDOverlapped.OffsetHigh = 0;
}
}
bool CUsbhidiocDlg::Receive(char *msgin)
{
if (MyDeviceDetected==FALSE)
MyDeviceDetected=Connect();
// Do nothing if the device isn't detected.
if (MyDeviceDetected==TRUE)
{
// Retrieve an Input report from the device.
DWORD Result;
//The first byte is the report number.
InputReport[0]=0;
/*API call:ReadFile
'Returns: the report in InputReport.
'Requires: a device handle returned by CreateFile
'(for overlapped I/O, CreateFile must be called with
FILE_FLAG_OVERLAPPED),
'the Input report length in bytes returned by HidP_GetCaps,
'and an overlapped structure whose hEvent member is set to an
event object. */
if (ReadHandle != INVALID_HANDLE_VALUE)
{
Result = ReadFile
(ReadHandle,
InputReport,
Capabilities.InputReportByteLength,
&NumberOfBytesRead,
(LPOVERLAPPED) &HIDOverlapped);
}
/*API call:WaitForSingleObject
'Used with overlapped ReadFile.
'Returns when ReadFile has received the requested amount of
data or on timeout.
'Requires an event object created with CreateEvent
'and a timeout value in milliseconds.*/
Result = WaitForSingleObject
(hEventObject,
6000);
switch (Result)
{
case WAIT_OBJECT_0:
{
memcpy(msgin,InputReport,sizeof(InputReport));
break;
}
case WAIT_TIMEOUT:
{
/*API call: CancelIo
Cancels the ReadFile
Requires the device handle.
Returns non-zero on success.*/
Result = CancelIo(ReadHandle);
33
//A timeout may mean that the device has been
removed.
//Close the device handles and set MyDeviceDetected
= False
//so the next access attempt will search for the
device.
Disconnect();
MyDeviceDetected = FALSE;
break;
}
default:
{
//Close the device handles and set MyDeviceDetected
= False
//so the next access attempt will search for the
device.
Disconnect();
MyDeviceDetected = FALSE;
break;
}
}
/*API call: ResetEvent
Sets the event object to non-signaled.
Requires a handle to the event object.
Returns non-zero on success.*/
ResetEvent(hEventObject);
}
return MyDeviceDetected;
}
bool CUsbhidiocDlg::Send(const char *msg)
{
if (MyDeviceDetected==FALSE)
MyDeviceDetected=Connect();
// Do nothing if the device isn't detected.
if (MyDeviceDetected==TRUE)
{
//Send a report to the device.
DWORD BytesWritten = 0;
INT Index =0;
ULONG Result;
memset(OutputReport,0,1);
memcpy(OutputReport+1,msg,8);
/*API Function: WriteFile
Sends a report to the device.
Returns: success or failure.
Requires:
A device handle returned by CreateFile.
A buffer that holds the report.
The Output Report length returned by HidP_GetCaps,
A variable to hold the number of bytes written.*/
if (WriteHandle != INVALID_HANDLE_VALUE)
{
Result = WriteFile
(WriteHandle,
OutputReport,
34
Capabilities.OutputReportByteLength,
&BytesWritten,
NULL);
}
if (!Result)
{
//The WriteFile failed, so close the handles, display a
message,
//and set MyDeviceDetected to FALSE so the next attempt
will look for the device.
Disconnect();
MyDeviceDetected = FALSE;
return false;
}
else
{
return true;
}
}
return MyDeviceDetected;
}
void main()
{
// TODO: code your application's behavior here.
CUsbhidiocDlg rope(0x04D8,0x1234);
bool status;
status = false;
status = rope.Connect();
status = false;
status = rope.Send("max8char");
char lido[9];
status = false;
status = rope.Receive(lido);
rope.Disconnect();
status = false;
}
• Este código é a implementação da corda em OpenGL #include <windows.h> // windows header
#include <gl\gl.h> //OpenGL library
#include <gl\glaux.h> //AUX library
#include <gl\glu.h> //Util library
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
GLfloat nRange = 500.0f;
void GameOver(void);
void DesenhaG(void);
void DesenhaO(void);
35
void DesenhaE(void);
void Contagem(void)
{
int cont=0;
int aux=4;
double coseno=0;
double seno=0;
glColor3f(1.0f, 0.0f, 0.0f);
//3
while(true)
{
if(aux==4)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20+40,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20-40,0.0f);
glTranslatef( coseno*20, 20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -20,0.0f);
aux--;
}
else if((aux<=3 && aux>=0)|| aux>=9)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20+40,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20-40,0.0f);
glTranslatef( coseno*20, seno*20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20,0.0f);
aux--;
}
else if(aux<0)
{
aux=12;
}
else if(aux=8)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20,0.0f);
break;
}
}
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//2
aux=1;
36
glTranslatef( -20.0f, 60.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -60.0f,0.0f);
glTranslatef( -17.0f, 70.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 17.0f, -70.0f,0.0f);
glTranslatef( -10.0f, 77.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, -77.0f,0.0f);
glTranslatef( 0.0f, 80.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -80.0f,0.0f);
glTranslatef( 10.0f, 77.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, -77.0f,0.0f);
glTranslatef( 17.0f, 70.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -17.0f, -70.0f,0.0f);
glTranslatef( 20.0f, 60.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, -60.0f,0.0f);
glTranslatef( 17.0f, 50.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -17.0f, -50.0f,0.0f);
glTranslatef( 10.0f, 43.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, -43.0f,0.0f);
glTranslatef( 0.0f, 40.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -40.0f,0.0f);
glTranslatef( -10.0f, 37.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, -37.0f,0.0f);
glTranslatef( -17.0f, 30.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 17.0f, -30.0f,0.0f);
glTranslatef( -20.0f, 20.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -20.0f,0.0f);
glTranslatef( -20.0f, 10.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -10.0f,0.0f);
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, 0.0f,0.0f);
glTranslatef( -10.0f, 0.0f,0.0f);
37
auxSolidSphere(10.0f);
glTranslatef( 10.0f, 0.0f,0.0f);
glTranslatef( 0.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, 0.0f,0.0f);
glTranslatef( 20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, 0.0f,0.0f);
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//1
while(cont<=80)
{
glTranslatef( 0.0f, 80.0f-cont,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -80.0f+cont,0.0f);
cont=cont+10;
}
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//GO!
aux=1;
glColor3f(0.0f, 1.0f, 0.0f);
glTranslatef( -70.0f, 0.0f,0.0f);
DesenhaG();
glTranslatef( 140.0f, 0.0f,0.0f);
aux=0;
DesenhaO();
glTranslatef( 90.0f, 60.0f,0.0f);
aux=0;
while(aux<=12)
{
if(aux<=8)
{
glTranslatef( 0.0f, -10.0f,0.0f);
auxSolidSphere(10.0f);
aux++;
}
else if(aux==12)
{
glTranslatef( 0.0f, -30.0f,0.0f);
auxSolidSphere(10.0f);
aux++;
}
else
{
38
aux++;
}
}
cont=0;
glTranslatef( -160.0f, 50.0f,0.0f);
glFlush();
Sleep(500);
//glClear(GL_COLOR_BUFFER_BIT);
}
void CALLBACK ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 500.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -
nRange*2.0f, nRange*2.0f);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -
nRange*2.0f, nRange*2.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void CALLBACK RenderScene(void)
{
int x=0,y=0;
double coseno=0;
double seno=0;
char sair;
glClearColor(0.0f, 0.0f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_LINE_STIPPLE);
Contagem();
//Desenha todas as lâmpadas da estrutura "apagadas"
while(x<=24)
{
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
//Esfera 1
glColor3f(0.5f, 0.5f, 0.5f);
glTranslatef( coseno*450, seno*450,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.5f, 0.5f, 0.0f);
39
auxSolidSphere(20.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
//Esfera 2
glColor3f(0.5f, 0.5f, 0.5f);
glTranslatef( coseno*390, seno*390,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.5f, 0.5f, 0.0f);
auxSolidSphere(20.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
//Esfera 3
glColor3f(0.5f, 0.5f, 0.5f);
glTranslatef( coseno*330, seno*330,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.5f, 0.5f, 0.0f);
auxSolidSphere(20.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
x++;
}
printf("Ta desenhado...");
printf("Iniciando o pisca-pisca");
x=16;
while(x>=0)
{
//Acende
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 1.0f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
Sleep(80);
//Apaga
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
glColor3f(0.5f, 0.5f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
40
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
x--;
if(x==0 && y<=10)
{
x=24;
y++;
}
if(x>=17 && x<=21)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glDrawPixels(10, 10, GL_RGBA, GL_UNSIGNED_BYTE, "A"
);
}
if(x>=17 && x<=21 && y>2)
{
glClear(GL_COLOR_BUFFER_BIT);
GameOver();
break;
}
}
}
void main(void)
{
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
auxInitPosition(0,0,800,600);
auxInitWindow("Transformacoes OpenGL");
auxReshapeFunc(ChangeSize);
auxMainLoop(RenderScene);
}
void GameOver(void)
{
int aux=0;
int tracoa=0;
int cont=0;
double coseno=0;
double seno=0;
glLoadIdentity();
//G
glColor3f(1.0f, 0.9f, 0.0f);
glTranslatef( -210.0f, 70.0f,0.0f);
DesenhaG();
glTranslatef( 200.0f, -70.0f,0.0f);
//A
glColor3f(1.0f, 0.8f, 0.0f);
41
aux=0;
while(cont<=6)
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
}
else if(cont==5)
{
glTranslatef( 0.0f, -10.0f,0.0f);
while(tracoa<=4)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
tracoa++;
}
}
else
{
glTranslatef( 40.0f, 10.0f,0.0f);
while(aux<=6)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
cont++;
}
//M
glColor3f(1.0f, 0.7f, 0.0f);
glTranslatef( 200.0f, -70.0f,0.0f);
cont=0;
while(cont<=6)
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
}
else if(cont>=5)
{
if(cont==5)
{
glTranslatef( -90.0f, 20.0f,0.0f);
}
else
{
glTranslatef( 60.0f, 0.0f,0.0f);
}
aux=0;
while(aux<=6)
42
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*30, seno*30,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*30, -seno*30,0.0f);
aux++;
}
}
cont++;
}
//E
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( 110.0f, -20.0f,0.0f);
DesenhaE();
//O
glTranslatef( -350.0f, -140.0f,0.0f);
glColor3f(1.0f, 0.5f, 0.0f);
DesenhaO();
//V
glColor3f(1.0f, 0.4f, 0.0f);
glTranslatef( 60.0f, 80.0f,0.0f);
cont=0;
while(cont<=12)
{
if(cont<=6)
{
glTranslatef( 8, -20.0,0.0f);
auxSolidSphere(10.0f);
cont++;
}
else
{
glTranslatef( 8, 20.0,0.0f);
auxSolidSphere(10.0f);
cont++;
}
}
//E
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( 70.0f, -60.0f,0.0f);
DesenhaE();
//R
glColor3f(1.0f, 0.1f, 0.0f);
glTranslatef( 180.0f, -70.0f,0.0f);
aux=0;
cont=0;
tracoa=0;
while(cont<=6)
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
}
43
else if(cont==5)
{
glTranslatef( 0.0f, -10.0f,0.0f);
while(tracoa<=4)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -50+tracoa*10,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, 50-tracoa*10,0.0f);
tracoa++;
}
}
else
{
glTranslatef( 40.0f, 10.0f,0.0f);
while(aux<=6)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
cont++;
}
glTranslatef( -70.0f, 0.0f,0.0f);
glFlush();
}
void DesenhaG(void)
{
int aux=0;
double coseno=0;
double seno=0;
while(aux<=15)
{
if(aux<=12)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
else if(aux<=15)
{
coseno=cos(aux*30*3.141592/180);
glTranslatef( coseno*60, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, 0.0f,0.0f);
aux++;
}
}
}
void DesenhaO(void)
{
44
int aux=0;
double coseno=0;
double seno=0;
while(aux<=15)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
void DesenhaE(void)
{
int aux=2;
double coseno=0;
double seno=0;
int tracoa=0;
while(aux<=10)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
if(aux==7)
{
glTranslatef( 20.0f, 0.0f,0.0f);
while(tracoa<=2)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
tracoa++;
}
glTranslatef( 40.0f, 0.0f,0.0f);
}
aux++;
}
}
• Este arquivo contém a integração do código de comunicação (anteriormente apresentado – USBhid.cpp) e o código da lógica da corda implementado em OpenGL separadamente.
// usbhid.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "usbhid.h"
#include <windows.h> // windows header
#include <gl\gl.h> //OpenGL library
#include <gl\glaux.h> //AUX library
#include <gl\glu.h> //Util library
#include <math.h>
#include <stdio.h>
#include <conio.h>
GLfloat nRange = 500.0f;
void GameOver(void);
void DesenhaG(void);
45
void DesenhaO(void);
void DesenhaE(void);
CUsbhidiocDlg::CUsbhidiocDlg(int vID, int pID)
{
VendorID = vID;
ProductID = pID;
MyDeviceDetected = false;
}
//Global Variables
HANDLE hEventObject;
void CUsbhidiocDlg::Disconnect()
{
//Close open handles.
if (DeviceHandle != INVALID_HANDLE_VALUE)
CloseHandle(DeviceHandle);
if (ReadHandle != INVALID_HANDLE_VALUE)
CloseHandle(ReadHandle);
if (WriteHandle != INVALID_HANDLE_VALUE)
CloseHandle(WriteHandle);
}
bool CUsbhidiocDlg::Connect()
{
//Use a series of API calls to find a HID with a specified Vendor IF
and Product ID.
HIDD_ATTRIBUTES Attributes;
SP_DEVICE_INTERFACE_DATA devInfoData;
bool LastDevice = FALSE;
int MemberIndex = 0;
LONG Result;
CString
UsageDescription;
Length = 0;
detailData = NULL;
DeviceHandle=NULL;
/*API function: HidD_GetHidGuid
Get the GUID for all system HIDs.
Returns: the GUID in HidGuid.*/
HidD_GetHidGuid(&HidGuid);
/*API function: SetupDiGetClassDevs
Returns: a handle to a device information set for all installed
devices.
Requires: the GUID returned by GetHidGuid.*/
hDevInfo=SetupDiGetClassDevs
(&HidGuid,
NULL,
NULL,
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
devInfoData.cbSize = sizeof(devInfoData);
//Step through the available devices looking for the one we want.
//Quit on detecting the desired device or checking all available
devices without success.
MemberIndex = 0;
LastDevice = FALSE;
46
do
{
/*API function: SetupDiEnumDeviceInterfaces
On return, MyDeviceInterfaceData contains the handle to a
SP_DEVICE_INTERFACE_DATA structure for a detected device.
Requires:
The DeviceInfoSet returned in SetupDiGetClassDevs.
The HidGuid returned in GetHidGuid.
An index to specify a device.*/
Result=SetupDiEnumDeviceInterfaces
(hDevInfo,
0,
&HidGuid,
MemberIndex,
&devInfoData);
if (Result != 0)
{
//A device has been detected, so get more information
about it.
/*API function: SetupDiGetDeviceInterfaceDetail
Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
containing information about a device.
To retrieve the information, call this function twice.
The first time returns the size of the structure in
Length.
The second time returns a pointer to the data in
DeviceInfoSet.
Requires:
A DeviceInfoSet returned by SetupDiGetClassDevs
The SP_DEVICE_INTERFACE_DATA structure returned by
SetupDiEnumDeviceInterfaces.
The final parameter is an optional pointer to an
SP_DEV_INFO_DATA structure.
This application doesn't retrieve or use the structure.
If retrieving the structure, set
MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
and pass the structure's address.*/
//Get the Length value.
//The call will return with a "buffer too small" error
which can be ignored.
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
NULL,
0,
&Length,
NULL);
//Allocate memory for the hDevInfo structure, using the
returned Length.
detailData =
(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
//Set cbSize in the detailData structure.
detailData -> cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
47
//Call the function again, this time passing it the
returned buffer size.
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
detailData,
Length,
&Required,
NULL);
// Open a handle to the device.
// To enable retrieving information about a system mouse
or keyboard,
// don't request Read or Write access for this handle.
/* API function: CreateFile
Returns: a handle that enables reading and writing to the
device.
Requires:
The DevicePath in the detailData structure
returned by SetupDiGetDeviceInterfaceDetail.*/
DeviceHandle=CreateFile
(detailData->DevicePath,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
/*API function: HidD_GetAttributes
Requests information from the device.
Requires: the handle returned by CreateFile.
Returns: a HIDD_ATTRIBUTES structure containing
the Vendor ID, Product ID, and Product Version Number.
Use this information to decide if the detected device is
the one we're looking for.*/
//Set the Size to the number of bytes in the structure.
Attributes.Size = sizeof(Attributes);
Result = HidD_GetAttributes
(DeviceHandle,
&Attributes);
//Is it the desired device?
MyDeviceDetected = FALSE;
if (Attributes.VendorID == VendorID)
{
if (Attributes.ProductID == ProductID)
{
//Both the Vendor ID and Product ID match.
MyDeviceDetected = TRUE;
MyDevicePathName = detailData->DevicePath;
//Get the device's capablities.
GetDeviceCapabilities();
// Get a handle for writing Output reports.
48
WriteHandle=CreateFile
(detailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
// Prepare to read reports using Overlapped
I/O.
PrepareForOverlappedTransfer();
} //if (Attributes.ProductID == ProductID)
else
//The Product ID doesn't match.
CloseHandle(DeviceHandle);
} //if (Attributes.VendorID == VendorID)
else
//The Vendor ID doesn't match.
CloseHandle(DeviceHandle);
//Free the memory used by the detailData structure (no
longer needed).
free(detailData);
} //if (Result != 0)
else
//SetupDiEnumDeviceInterfaces returned 0, so there are no
more devices to check.
LastDevice=TRUE;
//If we haven't found the device yet, and haven't tried every
available device,
//try the next one.
MemberIndex = MemberIndex + 1;
} //do
while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
//Free the memory reserved for hDevInfo by SetupDiClassDevs.
SetupDiDestroyDeviceInfoList(hDevInfo);
return MyDeviceDetected;
}
void CUsbhidiocDlg::GetDeviceCapabilities()
{
//Get the Capabilities structure for the device.
PHIDP_PREPARSED_DATA PreparsedData;
/*API function: HidD_GetPreparsedData
Returns: a pointer to a buffer containing the information about the
device's capabilities.
Requires: A handle returned by CreateFile.
There's no need to access the buffer directly,
but HidP_GetCaps and other API functions require a pointer to the
buffer.*/
HidD_GetPreparsedData
(DeviceHandle,
49
&PreparsedData);
/*API function: HidP_GetCaps
Learn the device's capabilities.
For standard devices such as joysticks, you can find out the specific
capabilities of the device.
For a custom device, the software will probably know what the device
is capable of,
and the call only verifies the information.
Requires: the pointer to the buffer returned by
HidD_GetPreparsedData.
Returns: a Capabilities structure containing the information.*/
HidP_GetCaps
(PreparsedData,
&Capabilities);
//No need for PreparsedData any more, so free the memory it's using.
HidD_FreePreparsedData(PreparsedData);
}
void CUsbhidiocDlg::PrepareForOverlappedTransfer()
{
//Get a handle to the device for the overlapped ReadFiles.
ReadHandle=CreateFile
(detailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
//Get an event object for the overlapped structure.
/*API function: CreateEvent Requires:
Security attributes or Null
Manual reset (true). Use ResetEvent to set the event object's state
to non-signaled.
Initial state (true = signaled)
Event object name (optional)
Returns: a handle to the event object*/
if (hEventObject == 0)
{
hEventObject = CreateEvent
(NULL,
TRUE,
TRUE,
LPCWSTR(""));
//Set the members of the overlapped structure.
HIDOverlapped.hEvent = hEventObject;
HIDOverlapped.Offset = 0;
HIDOverlapped.OffsetHigh = 0;
}
}
bool CUsbhidiocDlg::Receive(char *msgin)
{
if (MyDeviceDetected==FALSE)
MyDeviceDetected=Connect();
50
// Do nothing if the device isn't detected.
if (MyDeviceDetected==TRUE)
{
// Retrieve an Input report from the device.
DWORD Result;
//The first byte is the report number.
InputReport[0]=0;
/*API call:ReadFile
'Returns: the report in InputReport.
'Requires: a device handle returned by CreateFile
'(for overlapped I/O, CreateFile must be called with
FILE_FLAG_OVERLAPPED),
'the Input report length in bytes returned by HidP_GetCaps,
'and an overlapped structure whose hEvent member is set to an
event object. */
if (ReadHandle != INVALID_HANDLE_VALUE)
{
Result = ReadFile
(ReadHandle,
InputReport,
Capabilities.InputReportByteLength,
&NumberOfBytesRead,
(LPOVERLAPPED) &HIDOverlapped);
}
/*API call:WaitForSingleObject
'Used with overlapped ReadFile.
'Returns when ReadFile has received the requested amount of
data or on timeout.
'Requires an event object created with CreateEvent
'and a timeout value in milliseconds.*/
Result = WaitForSingleObject
(hEventObject,
6000);
switch (Result)
{
case WAIT_OBJECT_0:
{
memcpy(msgin,InputReport,sizeof(InputReport));
break;
}
case WAIT_TIMEOUT:
{
/*API call: CancelIo
Cancels the ReadFile
Requires the device handle.
Returns non-zero on success.*/
Result = CancelIo(ReadHandle);
//A timeout may mean that the device has been
removed.
//Close the device handles and set MyDeviceDetected
= False
//so the next access attempt will search for the
device.
Disconnect();
MyDeviceDetected = FALSE;
break;
51
}
default:
{
//Close the device handles and set MyDeviceDetected
= False
//so the next access attempt will search for the
device.
Disconnect();
MyDeviceDetected = FALSE;
break;
}
}
/*API call: ResetEvent
Sets the event object to non-signaled.
Requires a handle to the event object.
Returns non-zero on success.*/
ResetEvent(hEventObject);
}
return MyDeviceDetected;
}
bool CUsbhidiocDlg::Send(const char *msg)
{
if (MyDeviceDetected==FALSE)
MyDeviceDetected=Connect();
// Do nothing if the device isn't detected.
if (MyDeviceDetected==TRUE)
{
//Send a report to the device.
DWORD BytesWritten = 0;
INT Index =0;
ULONG Result;
memset(OutputReport,0,1);
memcpy(OutputReport+1,msg,8);
/*API Function: WriteFile
Sends a report to the device.
Returns: success or failure.
Requires:
A device handle returned by CreateFile.
A buffer that holds the report.
The Output Report length returned by HidP_GetCaps,
A variable to hold the number of bytes written.*/
if (WriteHandle != INVALID_HANDLE_VALUE)
{
Result = WriteFile
(WriteHandle,
OutputReport,
Capabilities.OutputReportByteLength,
&BytesWritten,
NULL);
}
if (!Result)
{
//The WriteFile failed, so close the handles, display a
message,
52
//and set MyDeviceDetected to FALSE so the next attempt
will look for the device.
Disconnect();
MyDeviceDetected = FALSE;
return false;
}
else
{
return true;
}
}
return MyDeviceDetected;
}
/*void main()
{
// TODO: code your application's behavior here.
CUsbhidiocDlg rope(0x04D8,0x1234);
bool status;
status = false;
status = rope.Connect();
status = false;
status = rope.Send("max8char");
char lido[9];
status = false;
status = rope.Receive(lido);
rope.Disconnect();
status = false;
}*/
void Contagem(void)
{
int cont=0;
int aux=4;
double coseno=0;
double seno=0;
glColor3f(1.0f, 0.0f, 0.0f);
//3
while(true)
{
if(aux==4)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20+40,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20-40,0.0f);
glTranslatef( coseno*20, 20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -20,0.0f);
aux--;
}
else if((aux<=3 && aux>=0)|| aux>=9)
53
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20+40,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20-40,0.0f);
glTranslatef( coseno*20, seno*20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20,0.0f);
aux--;
}
else if(aux<0)
{
aux=12;
}
else if(aux=8)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*20, seno*20,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*20, -seno*20,0.0f);
break;
}
}
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//2
aux=1;
glTranslatef( -20.0f, 60.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -60.0f,0.0f);
glTranslatef( -17.0f, 70.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 17.0f, -70.0f,0.0f);
glTranslatef( -10.0f, 77.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, -77.0f,0.0f);
glTranslatef( 0.0f, 80.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -80.0f,0.0f);
glTranslatef( 10.0f, 77.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, -77.0f,0.0f);
glTranslatef( 17.0f, 70.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -17.0f, -70.0f,0.0f);
glTranslatef( 20.0f, 60.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, -60.0f,0.0f);
54
glTranslatef( 17.0f, 50.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -17.0f, -50.0f,0.0f);
glTranslatef( 10.0f, 43.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, -43.0f,0.0f);
glTranslatef( 0.0f, 40.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -40.0f,0.0f);
glTranslatef( -10.0f, 37.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, -37.0f,0.0f);
glTranslatef( -17.0f, 30.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 17.0f, -30.0f,0.0f);
glTranslatef( -20.0f, 20.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -20.0f,0.0f);
glTranslatef( -20.0f, 10.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -10.0f,0.0f);
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, 0.0f,0.0f);
glTranslatef( -10.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, 0.0f,0.0f);
glTranslatef( 0.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 10.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -10.0f, 0.0f,0.0f);
glTranslatef( 20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, 0.0f,0.0f);
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//1
while(cont<=80)
{
glTranslatef( 0.0f, 80.0f-cont,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 0.0f, -80.0f+cont,0.0f);
cont=cont+10;
55
}
glFlush();
Sleep(1000);
glClear(GL_COLOR_BUFFER_BIT);
//GO!
aux=1;
glColor3f(0.0f, 1.0f, 0.0f);
glTranslatef( -70.0f, 0.0f,0.0f);
DesenhaG();
glTranslatef( 140.0f, 0.0f,0.0f);
aux=0;
DesenhaO();
glTranslatef( 90.0f, 60.0f,0.0f);
aux=0;
while(aux<=12)
{
if(aux<=8)
{
glTranslatef( 0.0f, -10.0f,0.0f);
auxSolidSphere(10.0f);
aux++;
}
else if(aux==12)
{
glTranslatef( 0.0f, -30.0f,0.0f);
auxSolidSphere(10.0f);
aux++;
}
else
{
aux++;
}
}
cont=0;
glTranslatef( -160.0f, 50.0f,0.0f);
glFlush();
Sleep(500);
//glClear(GL_COLOR_BUFFER_BIT);
}
void CALLBACK ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 500.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
56
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -
nRange*2.0f, nRange*2.0f);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -
nRange*2.0f, nRange*2.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void CALLBACK RenderScene(void)
{
CUsbhidiocDlg rope(0x04D8,0x1234);
char lido[2];
int x=0,y=0;
int vel=70;
double coseno=0;
double seno=0;
char sair;
bool jump = false;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_LINE_STIPPLE);
rope.Connect();
Contagem();
//Desenha todas as lâmpadas da estrutura "apagadas"
while(x<=24)
{
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
//Esfera 1
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.0f, 0.0f, 0.0f);
auxSolidSphere(20.0f);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
//Esfera 2
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.0f, 0.0f, 0.0f);
auxSolidSphere(20.0f);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
//Esfera 3
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxWireSphere(25.0f);
//Lâmpada
glColor3f(0.0f, 0.0f, 0.0f);
auxSolidSphere(20.0f);
57
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
x++;
}
printf("Ta desenhado...");
printf("Iniciando o pisca-pisca");
x=16;
while(x>=0)
{
//Acende
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
glColor3f(1.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 0.0f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 0.0f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 0.0f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+1)*15*3.141592/180);
seno=sin((x+1)*15*3.141592/180);
glColor3f(1.0f, 0.15f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 0.15f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 0.15f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 0.15f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+2)*15*3.141592/180);
seno=sin((x+2)*15*3.141592/180);
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
58
coseno=cos((x+3)*15*3.141592/180);
seno=sin((x+3)*15*3.141592/180);
glColor3f(1.0f, 0.45f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 0.45f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 0.45f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 0.45f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+4)*15*3.141592/180);
seno=sin((x+4)*15*3.141592/180);
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f);
auxSolidSphere(20.0f); // lâmpada 1
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f);
auxSolidSphere(20.0f); // lâmpada 2
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f);
auxSolidSphere(20.0f); // lâmpada 3
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
Sleep(vel);
//Apaga
coseno=cos(x*15*3.141592/180);
seno=sin(x*15*3.141592/180);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+1)*15*3.141592/180);
seno=sin((x+1)*15*3.141592/180);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
59
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+2)*15*3.141592/180);
seno=sin((x+2)*15*3.141592/180);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+3)*15*3.141592/180);
seno=sin((x+3)*15*3.141592/180);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
coseno=cos((x+4)*15*3.141592/180);
seno=sin((x+4)*15*3.141592/180);
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef( coseno*450, seno*450,0.0f); //lâmpada 1
auxSolidSphere(20.0f);
glTranslatef( coseno*-450, seno*-450,0.0f);
glTranslatef( coseno*390, seno*390,0.0f); //lâmpada 2
auxSolidSphere(20.0f);
glTranslatef( coseno*-390, seno*-390,0.0f);
glTranslatef( coseno*330, seno*330,0.0f); //lâmpada 3
auxSolidSphere(20.0f);
glTranslatef( coseno*-330, seno*-330,0.0f);
glFlush();
x--;
if(x==0)
{
x=24;
y++;
if (vel > 15)
if (y%5 == 0)
vel= vel - (vel/12);
system("cls");
printf("Velocidade: %i \n", vel);
printf("Pontos : %i \n", y);
}
if (x == 5 && y<3)
{
rope.Send("?");
rope.Receive(lido);
//printf("Sensor: %i \n", (int)lido[1]);
if (lido[1] < 4)
60
{
glClear(GL_COLOR_BUFFER_BIT);
GameOver();
break;
}
}
if(x>13 && x<20 && y>1)
{
rope.Send("?");
rope.Receive(lido);
//printf("Sensor: %i \n", (int)lido[1]);
if (lido[1] < 4)
{
jump = true;
}
}
if (x == 13 && y>1)
{
if (jump == false)
{
glClear(GL_COLOR_BUFFER_BIT);
GameOver();
break;
}
else
{
jump = false;
}
}
}
}
void main(void)
{
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
auxInitPosition(0,0,1350,800);
auxInitWindow(LPCWSTR("Transformacoes OpenGL"));
auxReshapeFunc(ChangeSize);
auxMainLoop(RenderScene);
}
void GameOver(void)
{
int aux=0;
int tracoa=0;
int cont=0;
double coseno=0;
double seno=0;
glLoadIdentity();
//G
glColor3f(1.0f, 0.9f, 0.0f);
glTranslatef( -210.0f, 70.0f,0.0f);
DesenhaG();
glTranslatef( 200.0f, -70.0f,0.0f);
//A
glColor3f(1.0f, 0.8f, 0.0f);
aux=0;
while(cont<=6)
61
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
}
else if(cont==5)
{
glTranslatef( 0.0f, -10.0f,0.0f);
while(tracoa<=4)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
tracoa++;
}
}
else
{
glTranslatef( 40.0f, 10.0f,0.0f);
while(aux<=6)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
cont++;
}
//M
glColor3f(1.0f, 0.7f, 0.0f);
glTranslatef( 200.0f, -70.0f,0.0f);
cont=0;
while(cont<=6)
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
}
else if(cont>=5)
{
if(cont==5)
{
glTranslatef( -90.0f, 20.0f,0.0f);
}
else
{
glTranslatef( 60.0f, 0.0f,0.0f);
}
aux=0;
while(aux<=6)
{
coseno=cos(aux*30*3.141592/180);
62
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*30, seno*30,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*30, -seno*30,0.0f);
aux++;
}
}
cont++;
}
//E
glColor3f(1.0f, 0.6f, 0.0f);
glTranslatef( 110.0f, -20.0f,0.0f);
DesenhaE();
//O
glTranslatef( -350.0f, -140.0f,0.0f);
glColor3f(1.0f, 0.5f, 0.0f);
DesenhaO();
//V
glColor3f(1.0f, 0.4f, 0.0f);
glTranslatef( 60.0f, 80.0f,0.0f);
cont=0;
while(cont<=12)
{
if(cont<=6)
{
glTranslatef( 8, -20.0,0.0f);
auxSolidSphere(10.0f);
cont++;
}
else
{
glTranslatef( 8, 20.0,0.0f);
auxSolidSphere(10.0f);
cont++;
}
}
//E
glColor3f(1.0f, 0.3f, 0.0f);
glTranslatef( 70.0f, -60.0f,0.0f);
DesenhaE();
//R
glColor3f(1.0f, 0.1f, 0.0f);
glTranslatef( 180.0f, -70.0f,0.0f);
aux=0;
cont=0;
tracoa=0;
while(cont<=6)
{
if(cont<=4)
{
glTranslatef( -120.0f, 14,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 120.0f, 0.0f,0.0f);
}
else if(cont==5)
{
63
glTranslatef( 0.0f, -10.0f,0.0f);
while(tracoa<=4)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( 20.0f, -50+tracoa*10,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -20.0f, 50-tracoa*10,0.0f);
tracoa++;
}
}
else
{
glTranslatef( 40.0f, 10.0f,0.0f);
while(aux<=6)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
cont++;
}
glTranslatef( -70.0f, 0.0f,0.0f);
glFlush();
}
void DesenhaG(void)
{
int aux=0;
double coseno=0;
double seno=0;
while(aux<=15)
{
if(aux<=12)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
else if(aux<=15)
{
coseno=cos(aux*30*3.141592/180);
glTranslatef( coseno*60, 0.0f,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, 0.0f,0.0f);
aux++;
}
}
}
void DesenhaO(void)
{
int aux=0;
double coseno=0;
64
double seno=0;
while(aux<=15)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
aux++;
}
}
void DesenhaE(void)
{
int aux=2;
double coseno=0;
double seno=0;
int tracoa=0;
while(aux<=10)
{
coseno=cos(aux*30*3.141592/180);
seno=sin(aux*30*3.141592/180);
glTranslatef( coseno*60, seno*60,0.0f);
auxSolidSphere(10.0f);
glTranslatef( -coseno*60, -seno*60,0.0f);
if(aux==7)
{
glTranslatef( 20.0f, 0.0f,0.0f);
while(tracoa<=2)
{
glTranslatef( -20.0f, 0.0f,0.0f);
auxSolidSphere(10.0f);
tracoa++;
}
glTranslatef( 40.0f, 0.0f,0.0f);
}
aux++;
}
}
65
Anexo 2 (Programas gravados no PIC) ; Software License Agreement
;
; The software supplied herewith by Dick Lichtel is intended
; for use solely and exclusively with the Quantum VFO
;
; The software is owned by the Company and/or its supplier, and is
protected under
; applicable copyright laws. All rights are reserved. Any use in violation
of the
; foregoing restrictions may subject the user to criminal sanctions under
applicable
; laws, as well as to civil liability for the breach of the terms and
conditions of
; this license.
;
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, WHETHER
EXPRESS,
; IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES
OF
; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS
SOFTWARE. THE
; COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
INCIDENTAL OR
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;
;##########################################################################
#####
; filename: MAIN.ASM
; Sample USB firmware
; Note: the E4_OSC_ config bit must be set for thing to work
properly
;
; The USB implementation is based upon the source code supplied by
MicroChip
; This implementation simply reads 8 bytes from the and returns them
;
; USB Commands:
;
; ?V Returns Version info (in descript.asm)
;##########################################################################
#####
;
; $Author: $
; Company:
;
; $Revision:$
; $Date: $
; Assembled using: MPASM 3.20.08
; Configuration Bits: E4 Oscillator, WDT Off, Power up timer off
; $History: $
;
;##########################################################################
######
;
; include files:
; P16C745.inc Rev 1.00
66
; usb_defs.inc Rev 1.10
;
;##########################################################################
######
#include <p16c745.inc>
#include "usb_defs.inc"
; External Clk with CLKOUT on OSC2, Watchdog timer off, Power-
up Timer off, no Code protected
__CONFIG _E4_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF
unbanked udata_shr
W_save res 1 ; register for saving W during ISR
Index res 1 ; Index for copying code string to ram
Source_PCL res 1 ; pointer to code string
Source_PCLATH res 1 ; pointer to code string
bank0 udata
Status_save res 1 ; registers for saving context
PCLATH_save res 1 ; during ISR
FSR_save res 1
INNER res 1
OUTER res 1
PIRmasked res 1
; User registers
d1 res 1 ; variavel auxiliar
d2 res 1 ; variavel auxiliar
ByteCount res 1 ; Number of bytes in Buffer
Buffer res 8 ; Location for data to be sent to host & data
from host
extern InitUSB
extern PutEP1
extern GetEP1
extern ServiceUSBInt
extern String3_l1
;************************************************
errorlevel -302 ; supress "register not in bank0, check page bits"
message
STARTUP code
pagesel Main
goto Main
nop
InterruptServiceVector
movwf W_save ; save W
movf STATUS,W
clrf STATUS ; force to page 0
movwf Status_save ; save STATUS
movf PCLATH,w
movwf PCLATH_save ; save PCLATH
movf FSR,w
movwf FSR_save ; save FSR
pagesel TMR0TEST
67
; *************************************************************
; Interrupt Service Routine
; First we step through several stages, attempting to identify the source
; of the interrupt.
; ******************************************************************
Process_ISR
TMR0TEST
btfsc INTCON,T0IE
btfss INTCON,T0IF
goto INTTEST
nop ; insert TMR0 code call here
INTTEST
btfsc INTCON,INTE
btfss INTCON,INTF
goto RBTEST
nop ; insert RB0/INT code call here
RBTEST
btfsc INTCON,RBIE
btfss INTCON,RBIF
goto PERIPHERALTEST
nop ; insert PORTB Change code call here
PERIPHERALTEST
btfss INTCON,PEIE ; is there a peripheral interrupt?
goto EndISR ; all done....
TEST_PIR1
banksel PIR1
movf PIR1,w
banksel PIE1
andwf PIE1,w ; mask the enables with the flags
banksel PIRmasked
movwf PIRmasked
pagesel ServiceUSBInt
btfsc PIRmasked,USBIF ; USB interrupt flag
call ServiceUSBInt ; Service USB interrupt
btfsc PIRmasked,ADIF ; AD Done?
nop
btfsc PIRmasked,RCIF
nop
btfsc PIRmasked,TXIF
nop
btfsc PIRmasked,CCP1IF
nop
btfsc PIRmasked,TMR2IF
nop
btfsc PIRmasked,TMR1IF
nop
TEST_PIR2
banksel PIR2
movf PIR2,w
banksel PIE2
andwf PIE2,w
banksel PIRmasked
movwf PIRmasked
btfsc PIRmasked,CCP2IF
nop
; ******************************************************************
68
; End ISR, restore context and return to the Main program
; ******************************************************************
EndISR
clrf STATUS ; select bank 0
movf FSR_save,w ; restore the FSR
movwf FSR
movf PCLATH_save,w ; restore PCLATH
movwf PCLATH
movf Status_save,w ; restore Status
movwf STATUS
swapf W_save,f ; restore W without corrupting STATUS
swapf W_save,w
retfie
code
Main
; ******************************************************************
; Sets the probe control register to output the UCTRL register and
; USBDPRAM databus onto the probepins.
; ******************************************************************
movlw .128 ; delay 16 uS to wait for USB to reset
movwf W_save ; SIE before initializing registers
decfsz W_save,f ; inner is merely a convienient register
goto $-1 ; to use for the delay counter.
pagesel InitUSB ; These six lines of code show the
appropriate
call InitUSB ; way to initialize the USB. First,
initialize
bsf OPTION_REG,NOT_RBPU ; disable portb weak pull-up
bcf STATUS,RP0 ; Make sure you include all pagesels and
return to
bcf STATUS,RP1 ; the desired bank (in this case Bank 0.)
ConfiguredUSB ; until the enumeration process to complete.
BCF STATUS, RP1 ;
BCF STATUS, RP0 ;
CLRF PORTA ; Initialize PORTA by
; clearing output
; data latches
BSF STATUS, RP0 ; Select Bank 1
MOVLW 0x06 ; Configure all pins
MOVWF ADCON1 ; as digital inputs
MOVLW 0xFE ; Value used to
; initialize data
; direction
MOVWF TRISA ; Set RA<3:0> as inputs
; RA<5:4> as outputs
; TRISA<7:6> are always
; read as ’0’.
;******************************************************************
;Now wait for something to arrive
69
;Data will be in Buffer
;******************************************************************
CheckEP1: ; Check Endpoint 1 for an OUT transaction
bankisel Buffer ; point to lower banks
pagesel GetEP1
banksel Buffer
movlw Buffer ; Data to be recv’d will be put in Buffer
movwf FSR ; point FSR to our buffer
call GetEP1 ; If data is ready, it will be copied.
pagesel CheckEP1
btfss STATUS,C ; was there any data for us?
goto CheckEP1 ; Nope, check again.
;if we receive a ?, return the PortA
movf Buffer,w
sublw '?'
btfss STATUS,Z
goto CheckEP1
BSF PORTA,0
call wait
PutBuffer
bankisel Buffer ; point to lower banks
pagesel PutEP1
movlw PORTA
movwf FSR ; point FSR to our buffer
movlw 0x01 ; send 1 bytes to the Host
call PutEP1
pagesel PutBuffer
btfss STATUS,C ; was it successful?
goto PutBuffer ; No: try again until successful
BCF PORTA,0
pagesel CheckEP1
goto CheckEP1 ; Yes: restart loop
wait
;7193 cycles
movlw 0x9E
movwf d1
movlw 0x06
movwf d2
wait_0
decfsz d1, f
goto $+2
decfsz d2, f
goto wait_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;****************************************
70
; Zeros the Buffer
;****************************************
ZeroBuffer:
banksel Buffer
variable i=0;
while(i<8)
clrf Buffer+i
i++
endw
return;
end
======================================================= ; Software License Agreement
;
; The software supplied herewith by Microchip Technology Incorporated (the
"Company")
; for its PICmicro(r) Microcontroller is intended and supplied to you, the
Company's
; customer, for use solely and exclusively on Microchip PICmicro
Microcontroller
; products.
;
; The software is owned by the Company and/or its supplier, and is
protected under
; applicable copyright laws. All rights are reserved. Any use in violation
of the
; foregoing restrictions may subject the user to criminal sanctions under
applicable
; laws, as well as to civil liability for the breach of the terms and
conditions of
; this license.
;
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, WHETHER
EXPRESS,
; IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES
OF
; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS
SOFTWARE. THE
; COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
INCIDENTAL OR
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;
;
###########################################################################
####
; filename: HIDCLASS.ASM
;
; Implements USB Human Interface Device (HID) class specific commands.
;
;
###########################################################################
####
;
; Author(s): Dan Butler and Reston Condit
; Company: Microchip Technology Inc
;
71
; Revision: 1.25
; Date: 14 March 2002
; Assembled using: MPASM 3.20
; $Header: $
;##########################################################################
######
;
; include files:
; P16C745.inc Rev 1.00
; usb_defs.inc Rev 1.10
;
;##########################################################################
######
#include <p16C745.inc>
#include "usb_defs.inc"
extern ReportDescriptor
extern ReportDescriptorLen
extern HID_Descriptor
extern Descriptions
extern BufferData
extern BufferDescriptor
extern wrongstate
extern USB_dev_req
extern EP0_maxLength
extern EP0_start
extern EP0_end
extern copy_descriptor_to_EP0
extern Send_0Len_pkt
extern Report_desc_index
global ClassSpecificRequest
USBBANK code
; ******************************************************************
; Get Class Specific Descriptor
; ******************************************************************
ClassSpecificRequest
pagesel Dev2HostHIDRequest
movf BufferData+bmRequestType,w
xorlw 0x21
btfsc STATUS,Z
goto Host2DevHIDRequest
pagesel Host2DevReportRequest
movf BufferData+bmRequestType,w
xorlw 0x22
btfsc STATUS,Z
goto Host2DevReportRequest
pagesel Host2DevPhysicalRequest
movf BufferData+bmRequestType,w
xorlw 0x23
btfsc STATUS,Z
goto Host2DevPhysicalRequest
pagesel Dev2HostHIDRequest
movf BufferData+bmRequestType,w
xorlw 0xA1
btfsc STATUS,Z
72
goto Dev2HostHIDRequest
pagesel Dev2HostReportRequest
movf BufferData+bmRequestType,w
xorlw 0xA2
btfsc STATUS,Z
goto Dev2HostReportRequest
pagesel Dev2HostPhysicalRequest
movf BufferData+bmRequestType,w
xorlw 0xA3
btfsc STATUS,Z
goto Dev2HostPhysicalRequest
pagesel wrongstate
goto wrongstate
; Need to add code if you need to handle optional functions
; such as get/set_idle. Otherwise, send STALL buy calling
; to signal the host that the feature is not implemented.
Host2DevHIDRequest
movf BufferData+bRequest,w
xorlw 0x01
pagesel GetHIDReport
btfsc STATUS,Z
goto GetHIDReport
movf BufferData+bRequest,w
xorlw 0x02
pagesel GetIdle
btfsc STATUS,Z
goto GetIdle
movf BufferData+bRequest,w
xorlw 0x03
pagesel GetPhysical
btfsc STATUS,Z
goto GetPhysical
movf BufferData+bRequest,w
xorlw 0x06
pagesel Get_Report_Descriptor
btfsc STATUS,Z
goto Get_Report_Descriptor
movf BufferData+bRequest,w
xorlw 0x09
pagesel SetHIDReport
btfsc STATUS,Z
goto SetHIDReport
movf BufferData+bRequest,w
xorlw 0x0A
pagesel SetIdle
btfsc STATUS,Z
goto SetIdle
movf BufferData+bRequest,w
xorlw 0x0B
pagesel SetProtocol
73
btfsc STATUS,Z
goto SetProtocol
pagesel wrongstate
goto wrongstate
; ******************************************************************
; Get Report Descriptor
; Returns the Mouse Report descriptor
; Checks for the report type (input, output or Feature).
; ******************************************************************
Get_Report_Descriptor
global Get_Report_Descriptor
banksel EP0_start
movlw GET_DESCRIPTOR
movwf USB_dev_req ; currently processing a get descriptor
request
movlw 8
movwf EP0_maxLength
movf BufferData+(wValue+1),w ; check report ID
xorlw 0x01 ; was it an Input Report?
pagesel TryOutputReport
btfsc STATUS,Z
goto TryOutputReport
bcf STATUS,C
rlf BufferData+wIndex,w
pagesel Report_desc_index
call Report_desc_index ; translate index to offset into descriptor
table
movwf EP0_start
bcf STATUS,C
rlf BufferData+wIndex,w
addlw 1 ; point to high order byte
call Report_desc_index ; translate index to offset into descriptor
table
movwf EP0_start+1
pagesel Descriptions
call Descriptions
movwf EP0_end
incf EP0_start,f
pagesel CheckReportLength
goto CheckReportLength
TryOutputReport
movf BufferData+(wValue+1),w ; check report ID
xorlw 0x02 ; was it an Output Report?
pagesel TryFeatureReport
btfsc STATUS,Z
goto TryFeatureReport
bcf STATUS,C
rlf BufferData+wIndex,w
pagesel Report_desc_index
call Report_desc_index ; translate index to offset into descriptor
table
movwf EP0_start
bcf STATUS,C
rlf BufferData+wIndex,w
74
addlw 1 ; point to high order byte
call Report_desc_index ; translate index to offset into descriptor
table
movwf EP0_start+1
pagesel Descriptions
call Descriptions
movwf EP0_end
incf EP0_start,f
pagesel CheckReportLength
goto CheckReportLength
TryFeatureReport
movf BufferData+(wValue+1),w ; check report ID
xorlw 0x03 ; was it an Output Report?
pagesel wrongstate
btfsc STATUS,Z
goto wrongstate
; Fill EP0IN buffer here...
return
CheckReportLength
movf BufferData+(wLength+1),w ; Is the host requesting more than 255
bytes?
pagesel nolimit_rpt
btfss STATUS,Z ; If so, the host is requesting more than we
have
goto nolimit_rpt
check_low_bytes
movf BufferData+wLength,w
subwf EP0_end,w ; if not, compare the amount the host is
request
movf BufferData+wLength,w ; with the length of the descriptor
btfsc STATUS,C ; if the host is request less than the
descriptor
movwf EP0_end ; length, send only as much as what the host
wants
nolimit_rpt
incf EP0_end,f
pagesel copy_descriptor_to_EP0
call copy_descriptor_to_EP0
return
Get_HID_Descriptor
global Get_HID_Descriptor
movlw GET_DESCRIPTOR
movwf USB_dev_req ; currently processing a get descriptor
request
movlw 8
movwf EP0_maxLength
movlw low HID_Descriptor
movwf EP0_start
movlw high HID_Descriptor
movwf EP0_start + 1
pagesel Descriptions
call Descriptions ; get the HID descriptor length
movwf EP0_end
75
movf BufferData+(wLength+1),f
pagesel nolimit_hid
btfss STATUS,Z
goto nolimit_hid
subwf BufferData+wLength,w
movf BufferData+wLength,w
btfss STATUS,C
movwf EP0_end
nolimit_hid
incf EP0_end,f
pagesel copy_descriptor_to_EP0
call copy_descriptor_to_EP0
return
Get_Physical_Descriptor
return
Check_Class_Specific_IN
global Check_Class_Specific_IN
pagesel copy_descriptor_to_EP0
movf USB_dev_req,w
xorlw GET_DESCRIPTOR
btfsc STATUS,Z
call copy_descriptor_to_EP0
return
; ******************************************************************
; These requests are parsed out, but nothing is actually done with them
; currently they simply stall EP0 to show that the request is not
; supported. If you need to support them, fill in the code.
; ******************************************************************
Host2DevReportRequest
Host2DevPhysicalRequest
Dev2HostHIDRequest
Dev2HostReportRequest
Dev2HostPhysicalRequest
GetHIDReport
GetIdle
GetPhysical
SetProtocol
SetIdle
pagesel wrongstate
goto wrongstate
SetHIDReport
movlw HID_SET_REPORT
movwf USB_dev_req ; store status
banksel BD0OST
return
end
76
Anexo 3 (Pseudocódigo do ROPE Simulator) • Pseudocódigo construído durante o projeto e mantido para documentação
histórica do projeto START
X=0; //X equivale ao sensor que será testado
Ponto=0;
ENQUANTO(1) //Tempo que a corda está passando por cima da cabeça
do jogador, nenhum status se sensor é verificado
TEMPO(10s);
//Teste dos sensores
ENQUANTO(X ≤ Nº de sensores) // testa a tensão na saída do sensor para detectar a presença
ENVIA(PIC); //rope.Send("?");
SE(Tensão em X==1)
//passa para o próximo sensor
ENTÃO X=X+1;
SENÃO STOP EXIBIR(Ponto); FIM_ENQUANTO; SE(X > Nº de sensores) X=0;
Ponto++;
FIM_ENQUANTO; END
77
Anexo 4 – FOTOS
Foto 2: Módulo dos sensores
Foto 3: Marca – ROPE Simulator
78
Foto 4: Multivibrador + Receptor infravermelho
Foto 5: Estrutura física