TODOPIC

Lenguajes de programación para PC => C, C#, C++ => Mensaje iniciado por: migsantiago en 21 de Abril de 2006, 16:41:47

Título: Manejo de tiempos eficaz
Publicado por: migsantiago en 21 de Abril de 2006, 16:41:47
Hola

He aprendido a usar visual c++ mediante ebooks, y sé muy pocos comandos y formas de hacer las cosas.

Para manejar el puerto paralelo uso el método que publico en un tema en este subforo. Mi forma de usar tiempos es mediante SetTimer(). Tengo entendido que también existe sleep() pero nunca la he usado, porque creo que ocupa el procesador al 100% y SetTimer se maneja como evento. Con SetTimer se pueden hacer cosas mientras el reloj está contando, pero me parece que con sleep no se puede.

Bueno, usando SetTimer manejo los tiempos de salidas al puerto paralelo, pero me doy cuenta que si el procesador está muy ocupado, esos tiempos ya no se cumplen. Adjunto un programa exe que hace uso de settimer y que maneja tiempos de 1ms a 1000ms para alternar las salidas D0, D1 y D2 de 0x378.

No tengo osciloscopio ni equipo para medir tiempos, pero me doy cuenta que el tiempo que uno introduce no se cumple, principalmente en tiempos pequeños como 5ms.

Ahora bien, ¿podría alguien darme una manera eficaz para manejar tiempos en visualc++? Podría ser solo la referencia para empezarlo a estudiar. Talvez sea necesario usar interrupciones por software.

Por si les interesa, aquí pego el código que uso para generar los eventos del timer...

Código: [Seleccionar]
void CMotordiscoduroDlg::OnGiro()
{
MessageBeep(MB_OK); //avisa
GetDlgItem(IDC_GIRO)->EnableWindow(FALSE); //deshabilita botón
GetDlgItem(IDC_HORARIO)->EnableWindow(FALSE); //deshabilita botón
GetDlgItem(IDC_ANTIHORARIO)->EnableWindow(FALSE); //deshabilita botón
GetDlgItem(IDC_DETENER)->EnableWindow(TRUE); //habilita botón
SetTimer(tiempo1,m_velocidad,NULL); //habilita el timer de los pasos del motor
UpdateData(TRUE); //recoge datos de pantalla
}

Código: [Seleccionar]
void CMotordiscoduroDlg::OnTimer(UINT nIDEvent)
{
UpdateData(TRUE); //refresca m_velocidad
SetTimer(tiempo1,m_velocidad,NULL); //refresca el timer de los pasos del motor
//MessageBeep(MB_OK); //avisa que entró a timer

//aquí llega cada m_velocidad ms
switch(estado_prox)
{
case 1:
PortOut(puerto_par,estado1);
break;
case 2:
PortOut(puerto_par,estado2);
break;
case 3:
PortOut(puerto_par,estado3);
break;
case 4:
PortOut(puerto_par,estado4);
break;
case 5:
PortOut(puerto_par,estado5);
break;
case 6:
PortOut(puerto_par,estado6);
break;
}

//aquí se indica el siguiente paso a dar, los pasos válidos van del 1 al 6, por lo que 0
//se convierte en 6, y 7 se convierte en 1
if(m_giro==1)
{
estado_prox--; //antihorario
if(estado_prox==0)
estado_prox=6; //reinicia ciclos
}

if(m_giro==0)
{
estado_prox++; //horario
if(estado_prox==7)
estado_prox=1; //reinicia ciclos
}

CDialog::OnTimer(nIDEvent);
}

Me interesa el uso de Visual C++ para enfocarlo a la electrónica, talvez visual c++ solo sirva para otras aplicaciones  :(

Título: Re: Manejo de tiempos eficaz
Publicado por: migsantiago en 23 de Abril de 2006, 16:56:21
Adjunto Parallel Monitor de

http://www.geekhideout.com/parmon.shtml

por si les interesa ver como son las salidas del puerto paralelo. Muestra gráficamente el estado de las terminales del puerto paralelo y permite modificarlas.

EDITO: Encontré información sobre manejo de timers.

--------------------
BTW, if you are running Windows NT, check out these APIs. You'll get better than 1 ms and you don't have to QueryPerformanceCounter().

The APIs are
CreateWaitableTimer() - creates a periodic or one shot timer
OpenWaitableTimer() - opens an existing timer object
SetWaitableTimer() - sets the timing and periodicity of timer
CancelWaitableTimer() - cancels the timer setting
CloseHandle() - shuts down the timer
WaitForSingleObject() - waits for timer to complete one cycle (timer will signal its handle)
------------------------

No entiendo como se usan, pero les dejo la referencia.

Por ahora me conformaré con el uso de settimer.  :-/
Título: Re: Manejo de tiempos eficaz
Publicado por: Geo en 25 de Abril de 2006, 01:39:48
Puedes probar también con estas:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timegettime.asp

Saludos,
José Jorge (Geo).
Título: Re: Manejo de tiempos eficaz
Publicado por: migsantiago en 25 de Abril de 2006, 12:30:48
Hola Geo

Gracias por la información, pero solo dice que es para saber el tiempo que lleva ejecutándose windows. Me va a ser útil para medir el tiempo real que tarda mi aplicación en mandar un paso tras otro. Aunque hay un problema:

Windows NT/2000: The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime.

Yo necesito ver si realmente es 1ms el tiempo que tarda y esa función me va a entregar una medición mayor a 5ms  :(

Dejo otros link interesantes.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timesetevent.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timebeginperiod.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timeendperiod.asp
Título: Re: Manejo de tiempos eficaz
Publicado por: Geo en 26 de Abril de 2006, 01:38:50
Windows NT/2000: The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime.

Es la precisión por defecto, pero con las otras funciones puedes modificarla (creo que hasta 1 ms). En realidad no las he utilizado :P.

Saludos,
José Jorge (Geo).
Título: Re: Manejo de tiempos eficaz
Publicado por: migsantiago en 26 de Abril de 2006, 13:15:20
Sí, lo intenté con el Begin y el End para modificar la resolución, pero no pude compilarlo, no sé cómo se declaran las funciones, a pesar de que incluí la librería winmm.lib.  :(

Los links a esas funciones están arriba.  :)