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
Í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
Í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
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.
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]tecnologia, os procedimentos de testes e validação do projeto, analise de risco de
desenvolvimento e implementação e o cronograma atualizado.
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
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,
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]
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.
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.
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.
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.
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.
Figura 13: Layout da placa construída na estrutura física
•
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.
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
A interface gráfica do projeto, depois de implementada deve ficar similar ao
esboço já apresentado no Plano de Projeto.
Figura 17: Interface visual implementada e apresentada
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.
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!
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!
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.
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(); };
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;
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);
//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.*/
{
//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;
/*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.
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);
//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
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 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( -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);
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)
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
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);
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);
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);
{
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); }
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++;
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 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.
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 =
//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;
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,
&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(""));
// 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;
}
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.*/
//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--;
}
{
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( 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;
} 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) {
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);
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);
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);
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++;
{ 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)
{ 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)
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) {