Secuencias Independientes Utilizando Lenguaje Pawn

  • 3 Respuestas
  • 4252 Vistas

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2326
  • Soporte Técnico
Secuencias Independientes Utilizando Lenguaje Pawn
« : septiembre 24, 2012, 22:46:37 pm »
La siguiente es una consulta de FenixBioEnergy y contestamos en el siguiente mensaje:

Citar

Asunto: consulta
De: FenixBioEnergy: Hoy a las 04:44:38

Boris, buenas tardes soy ariel, de fenix bioenergy, estaba con el plc y tengo un inconveniente de programación que quería consultarte, el plc lo vamos a usar para un enfriador de contra-flujo, tiene dos puertas trampas neumáticas que tiene que abrir y cerrar una encima de otra

Código: [Seleccionar]
PlcMain()
{
   LcdClear()
        LcdPrintf(0,0, "FENIX BIOEENERGY")
   PauseMS (4000)
   LcdClear()
        LcdPrintf(0,0, "ENFRIADOR OK")
        PauseMS (4000)
   LcdClear()
        LcdPrintf(0,0, "****CUIDADO*****")
        PauseMS (3000)
        LcdPrintf(0,0, "CONECCION TURBINA")
        PauseMS (3000)
   RelayClose (RELAY4)
   DelayMS (3000)
   LcdPrintf(0,0, " TURBINA CONECTADA")
        PauseMS (3000)
   while(true)
   {
   RelayOpen (RELAY3)
   DelayMS (3000)
   RelayClose (RELAY3)
   DelayMS (500)
   RelayOpen (RELAY5)
   DelayMS (3000)
   RelayClose (RELAY5)
   DelayMS (500)
   }
}

Eso ya esta, ahora me falta la secuencia de la puerta de descarga, pero que sea aparte de la de secuencia de descarga.

Desde ya muchas gracias, la verdad los productos excelentes!!

Ariel Cruz.

« Última Modificación: septiembre 25, 2012, 16:14:56 pm por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2326
  • Soporte Técnico
Re: Secuencias Independientes Utilizando Lenguaje Pawn
« Respuesta #1 : septiembre 24, 2012, 23:04:24 pm »
Buenas tardes Ariel,

Leyendo tu mensaje, supongo que necesitas crear dos secuencias
que se ejecuten independientemente en lenguaje Pawn.

Viendo tu código, el inconveniente es el utilizar retardos
para realizar la secuencias de activación de reles, ya que esto
requiere implementar código adicional.

Es posible hacer dos secuencias independientes, pero
al utilizar retardos necesitas crear funciones que no te bloqueen
la ejecución del programa.

Es decir, la secuencia A debe llamarse y retornar inmediatamente
para llamar a la secuencia B, que tiene que ejecutar otro codigo.

Utilizando los timers del PLC es posible hacer "timeouts" a medida
para esto.

Te adjunto el mismo codigo que me pasaste en un proyecto
nuevo con dos secuencias:

Secuencia A: Conmuta los RELAY3 y RELAY5 segun tu logica.

Secuencia B: Conmuta los RELAY7 y RELAY8 solo para ejemplificar.

Compila el proyecto con StxLadder y ejecutalo en tu PLC para que veas
como las dos secuencias se ejecutan independientemente.

Cree en el proyecto dos funciones llamadas: CheckTimeoutCS() y SetTimeoutCS()
que son para comprobar y crear un timeout.

En el proyecto utilizo el timer1 para decrementar los timeout.

En Lenguaje Ladder es mas simple hacer este tipo de lógica, utilizando
los "Timer Ladders", pero es a titulo informativo.

El proyecto lo podes descargar de

www.slicetex.com/temp/FenixBioEnergy.zip

Igual posteo el código a continuación.

Espero haber entendido tu consulta y cualquier duda, avísanos.

Código: [Seleccionar]

// --------------------------------------------------------------------------------
// Archivo      : PlcMain.p
// Titulo       : Script principal del PLC.
//
// Creado por   : StxLadder Version 1.0.7.
// Fecha        : 24/09/2012 19:49:38
//
// Descripcion  :
//
// Aqui puede describir su proyecto.
//
// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
// VARIABLES GLOBALES
// --------------------------------------------------------------------------------

// Timeout-1 en Centesimas de Segundos.
new Timeout1CS = 0

// Timeout-2 en Centesimas de Segundos.
new Timeout2CS = 0

// Almacena el numero de paso de la secuencia A.
new SecuenciaA_Paso = 0

// Almacena el numero de paso de la secuencia B.
new SecuenciaB_Paso = 0

// ********************************************************************************
// Funcion     : PlcMain()
// Descripcion : Punto de entrada principal del PLC.
// ********************************************************************************

PlcMain()
{
// Activa el timer1 para generar un evento cada 100 mS.
Timer1SetEvent(100, true)

   // INICIO
   LcdClear()
   LcdPrintf(0,0, "FENIX BIOEENERGY")
   PauseMS(4000)
   LcdClear()
   LcdPrintf(0,0, "ENFRIADOR OK")
   PauseMS(4000)
   LcdClear()
   LcdPrintf(0,0, "****CUIDADO*****")
   PauseMS(3000)
   LcdPrintf(0,0, "CONEXION TURBINA")
   PauseMS(3000)
   RelayClose (RELAY4)
   DelayMS(3000)
   LcdPrintf(0,0, " TURBINA CONECTADA")
   PauseMS(3000)
  
   // EMPEZAR SECUENCIA A POR PASO 1:
   SecuenciaA_Paso = 1
  
   // EMPEZAR SECUENCIA B POR PASO 1:
   SecuenciaB_Paso = 1
  
   // LOOP PRINCIPAL
  
   while(true)
   {
  // Iniciar Secuencia A.
  SecuenciaA(SecuenciaA_Paso)
 
  // Iniciar Secuencia B.
  SecuenciaB(SecuenciaB_Paso)
   }
  
   // Retorno.
   return 0
}


// ********************************************************************************
// Funcion     : OnTimer1()
// Descripcion : Evento OnTimer1 utilizado para actualizar los timeouts en
//               centi-segundos.
// ********************************************************************************

@OnTimer1()
{
// Decrementa timeout 1.
if(Timeout1CS > 0)
{
Timeout1CS--
}

// Decrementa timeout 2.
if(Timeout2CS > 0)
{
Timeout2CS--
}
}

// ********************************************************************************
// Funcion     : SecuenciaA()
// Descripcion : Secuencia A
//
// Entradas    :
//
//          - paso = Numero de paso a ejecutar.
//
// ********************************************************************************

SecuenciaA(paso)
{
switch(paso)
{
// Paso 1.
case 1:
{
RelayOpen (RELAY3)

// Establecer un Timeout en 30 centi-segundos.
SetTimeout1CS(30)

// Especificar proximo Paso.
SecuenciaA_Paso = 2
}

// Paso 2.
case 2:
{
// Comprobar Timeout.
if(CheckTimeout1CS())
{
// Timeout!... Especificar proximo paso.
SecuenciaA_Paso = 3
}
}

// Paso 3.
case 3:
{
RelayClose(RELAY3)
SetTimeout1CS(5)
SecuenciaA_Paso = 4
}

// Paso 4.
case 4:
{
if(CheckTimeout1CS())
{
SecuenciaA_Paso = 5
}
}

// Paso 5.
case 5:
{
RelayOpen (RELAY5)
SetTimeout1CS(30)
SecuenciaA_Paso = 6
}

// Paso 6.
case 6:
{
if(CheckTimeout1CS())
{
SecuenciaA_Paso = 7
}
}

// Paso 7.
case 7:
{
RelayClose(RELAY5)
SetTimeout1CS(5)
SecuenciaA_Paso = 8
}

// Paso 8.
case 8:
{
if(CheckTimeout1CS())
{
// Volver al inicio de la secuencia.
SecuenciaA_Paso = 1
}
}
}
}

// ********************************************************************************
// Funcion     : SetTimeout1CS()
// Descripcion : Establece un timeout en 'cs' centi-segundos.
//
// Entradas    :
//
//          - cs = Tiempo para el timeout en centi-segundos (resolucion 100 ms).
// ********************************************************************************

SetTimeout1CS(cs)
{
   Timeout1CS = cs
}

// ********************************************************************************
// Funcion     : CheckTimeout1CS()
// Descripcion : Comprueba Timeout1CS, retorna 1 si hay un timeout.
//               Retorn 0 si no hay timeout.
// ********************************************************************************

CheckTimeout1CS()
{
   if(Timeout1CS <= 0)
   {
  // Timeout!.
  return 1
   }
   else
   {
  // No hay timeout.
  return 0
   }  
}


// ********************************************************************************
// Funcion     : SecuenciaB()
// Descripcion : Secuencia B
//
// Entradas    :
//
//          - paso = Numero de paso a ejecutar.
//
// ********************************************************************************

SecuenciaB(paso)
{
switch(paso)
{
// Paso 1.
case 1:
{
RelayOpen(RELAY7)

// Establecer un Timeout en 30 centi-segundos.
SetTimeout2CS(30)

// Especificar proximo Paso.
SecuenciaB_Paso = 2
}

// Paso 2.
case 2:
{
// Comprobar Timeout.
if(CheckTimeout2CS())
{
// Timeout!... Especificar proximo paso.
SecuenciaB_Paso = 3
}
}

// Paso 3.
case 3:
{
RelayClose(RELAY7)
SetTimeout2CS(5)
SecuenciaB_Paso = 4
}

// Paso 4.
case 4:
{
if(CheckTimeout2CS())
{
SecuenciaB_Paso = 5
}
}

// Paso 5.
case 5:
{
RelayOpen(RELAY8)
SetTimeout2CS(30)
SecuenciaB_Paso = 6
}

// Paso 6.
case 6:
{
if(CheckTimeout2CS())
{
SecuenciaB_Paso = 7
}
}

// Paso 7.
case 7:
{
RelayClose(RELAY8)
SetTimeout2CS(5)
SecuenciaB_Paso = 8
}

// Paso 8.
case 8:
{
if(CheckTimeout2CS())
{
// Volver al inicio de la secuencia.
SecuenciaB_Paso = 1
}
}
}
}

// ********************************************************************************
// Funcion     : SetTimeout2CS()
// Descripcion : Establece un timeout en 'cs' centi-segundos.
//
// Entradas    :
//
//          - cs = Tiempo para el timeout en centi-segundos (resolucion 100 ms).
// ********************************************************************************

SetTimeout2CS(cs)
{
   Timeout2CS = cs
}

// ********************************************************************************
// Funcion     : CheckTimeout2CS()
// Descripcion : Comprueba Timeout2CS, retorna 1 si hay un timeout.
//               Retorn 0 si no hay timeout.
// ********************************************************************************

CheckTimeout2CS()
{
   if(Timeout2CS <= 0)
   {
  // Timeout!.
  return 1
   }
   else
   {
  // No hay timeout.
  return 0
   }  
}







« Última Modificación: septiembre 25, 2012, 13:22:55 pm por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

FenixBioEnergy

  • Novato
  • *
  • Mensajes: 13
Re: Secuencias Independientes Utilizando Lenguaje Pawn
« Respuesta #2 : septiembre 25, 2012, 00:08:38 am »
Boris, Excelente respuesta, es exactamente lo que tenia que hacer, pero la secuencia b es un ping pong, no se superponen, pero son dos secuencias totalmente separadas y variables sin afectar una a la otra, obvio que la proxima es con ladder,  una pregunta mas, si quiero que la secuencia  b comience con uno de los relays (7) cerrados por digamos 7min (asi carga material), y luego comience la secuencia continua de hacer un swap al 8 por 15seg y volver al 7 , con frecuencia de 1 minuto (puerta neumatica de apertura para descarga) se puede!? osea la puerta tendria que permanecer cerrada por 7 minutos para poder cargar a nivel el material a enfriar, para luego cada un minuto abrir (Relay 8) por 15 seg(aprox) para dosificar la descarga. desde ya muchas gracias!! la verdad el tiempo de respuesta y el soporte es increible!!!


ariel Cruz
Fenix Bioenergy

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2326
  • Soporte Técnico
Re: Secuencias Independientes Utilizando Lenguaje Pawn
« Respuesta #3 : septiembre 25, 2012, 12:56:05 pm »
Estimado Ariel,

Seguro se puede, creo que para ello deberias modificar la secuencia B de la siguiente forma:

Código: [Seleccionar]

SecuenciaB(paso)
{
switch(paso)
{
// Paso 1.
case 1:
{
RelayClose(RELAY7)

// Establecer un Timeout en 42000 centi-segundos (7 minutos)
SetTimeout2CS(42000)

// Especificar proximo Paso.
SecuenciaB_Paso = 2
}

// Paso 2.
case 2:
{
// Comprobar Timeout.
if(CheckTimeout2CS())
{
// Timeout!... Especificar proximo paso.
SecuenciaB_Paso = 3

// Abrir RELAY7
RelayOpen(RELAY7)
}
}

// Paso 3.
case 3:
{
RelayClose(RELAY8)

// Esperar 15 segundos.
SetTimeout2CS(150)

SecuenciaB_Paso = 4
}

// Paso 4.
case 4:
{
if(CheckTimeout2CS())
{
SecuenciaB_Paso = 5

// Cerrar RELAY8
RelayCloseRELAY8)
}
}

// Paso 5.
case 5:
{
// Esperar 45 segundos.
SetTimeout2CS(450)
SecuenciaB_Paso = 6
}

// Paso 6.
case 6:
{
if(CheckTimeout2CS())
{
// Volver al Paso 3.
SecuenciaB_Paso = 3
}
}
}
}


Lo importante es que entiendas que tus funciones no deben "bloquear" la ejecucion
del código, ya que eso retardaría la ejecución de otra secuencia, porque ambas se estan
ejecutando constantemente en "paralelo".

Por ello, cada secuencia ejecuta un paso a la vez, y no pasa al siguiente paso
hasta que explicitamente lo especifiquemos.

En este caso, la secuencia B empieza cerrando el RELAY7 por 7 minutos,
luego lo abre en el paso 2, y en el paso 3 cierra el RELAY8 por 15 segundos. En paso 4 lo abre al RELAY8
y en el paso 5 espera 45 segundos. Finalmente el paso 6 especifica que la secuencia
vuelva al paso 3 para repetir la secuencia desde ese punto.

Esa es la forma de hacer dos secuencias totalmente independientes, quizás
pueda simplificarse pero eso depende de como implementes tu proyecto.

Cualquier consulta quedamos a disposición.



« Última Modificación: septiembre 25, 2012, 13:24:42 pm por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com