Error MODBUS - Solucionado

  • 7 Respuestas
  • 270 Vistas

guille

  • Novato
  • *
  • Mensajes: 16
Error MODBUS - Solucionado
« : septiembre 20, 2016, 19:39:05 pm »
Hola Boris,

estoy programando en PAWN utilizando el HMI ARRAY SH300 y venia todo bien, hasta que en un momento empezó a titilar el Led DEBUG del PLC y el HMI ya no actualiza los valores que le envío, como los valores de RTC....

Después de buscar el problema me di cuenta de lo siguiente: yo inicio el servidor con el siguiente código, obtenido de de la AN023.pdf, a saber:

if(MbRtuServInit(1, 9600, SERIAL_8E1, MB_RTU_INTERFACE_RS232) < 0)
{
// Error, pausar programa en este punto.
while(true)
{
DelayMS(2000)
LedToggle()
}
}

Me di cuenta que la función estaba retornando un valor menor a 0 y el programa quedaba pausado ahí...

Modifique el código de modo de mostrar que retornaba dicha función de inicialización y observe que me devuelve -1, o sea, "Error, el servidor ya se encuentra inicializado"..... Venia programando normal, sin errores, y de la nada apareció esto. Obviamente solo invoco esa función una vez, por lo cual no se porque me dice esto! Probé restaurar los valores de fabrica del PLC, reseteando con la combinación "DEF/BOOT" y "RESET", como indicas aquí en el foro. El error persiste!!

Porque me dice que ya esta iniciado el servidor Modbus aunque solo invoque 1 vez dicha función? Puedo seguir utilizándolo aun con este valor de error?? Que se puede hacer para volver a la normalidad?

Adjunto el código (casi) completo por las dudas:

///////////////////////////////////////////////////////////////////////////////////////////////////

PlcMain()
{
   // Crear variables para almacenar información del reloj.
   new Day, Month, Year, Hour, Min, Sec, DOW
     
   //Inicia servidor ModBus
   
   new R = MbRtuServInit(1, 9600, SERIAL_8E1, MB_RTU_INTERFACE_RS232);
         if(R < 0)
         {
            MbRtuServLoadRegister(42017, R)         
            while(true)
            {
            DelayMS(2000)
            LedToggle()
            }
          }
         
   // Inicializar placa STX570, dirección 0, conectada al puerto de expansión.
   //Stx570_Init(0)
   
   //Evento RTC
   RtcOnSecondSetEvent()
   
   //Lee EEPROM Programa A, TiempoUsoHs
   EepromRead(1,9,A)
   MbRtuServLoadRegisters(42001,9, A)

   EepromReadByte(0,TiempoUsoHs)
   MbRtuServLoadRegister(42017, TiempoUsoHs)
   
   while(true)
   {
      // Obtener información del reloj.
      RtcGetAll(Day, Month, Year, Hour, Min, Sec, DOW) //Reg 42010 al 42015
           
      MbRtuServLoadRegister(42010, Day)
      MbRtuServLoadRegister(42011, Month)
      MbRtuServLoadRegister(42012, Year)
      MbRtuServLoadRegister(42013, Hour)
      MbRtuServLoadRegister(42014, Min)
      MbRtuServLoadRegister(42015, Sec)
      //MbRtuServLoadRegister(42017, TiempoUsoHs)

      //Elige programa
      MbRtuServGetRegister(42018, Programa)
     
      //Comprueba si se ha modificado un programa
      MbRtuServGetRegister(42019, Config)
     
      //Iniciar Programa
      MbRtuServGetRegister(42020, Start)
     
      //Guarda las modificaciones realizadas sobre el programa en EEPROM
      if(Config)
         {
               Config=0
               DelayS(2)
               MbRtuServLoadRegister(42019, Config)
               
               MbRtuServGetRegisters(42001,9,A)
               EepromWrite(1,9,A)
               
               MbRtuServLoadRegisters(42001,9, A)
         
         }
   // Retorno.
   
   return 0
   }
}
   

//Interrupcion cada 1 seg - RTC
  @OnRtcSecond()
{
      CountMinReset++
      MbRtuServLoadRegister(42016, CountMinReset)
     
      if(CountMinReset==59)
         {
            CountMinReset = 0
            TiempoUsoHs++
            MbRtuServLoadRegister(42017, TiempoUsoHs)
           
            //EepromWriteByte(0, TiempoUsoHs)
           
         }
}

Gracias !!
« Última Modificación: septiembre 29, 2016, 20:46:08 pm por Soporte »

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 1625
  • Soporte Técnico
Re:Error MODBUS
« Respuesta #1 : septiembre 21, 2016, 10:08:43 am »
Buenos días Guillermo,

¿ Es posible que me envíes el proyecto completo así pruebo el código original ?.
Lo podes comprimir todo en un archivo desde el menú "Archivo > Crear backup del proyecto" en StxLadder y adjuntarlo aquí.

Por otro lado, ¿ si probas los ejemplos originales, también tenes falla ?.

Carga por ejemplo:

Al PLC:

http://slicetex.com/docs/an/an023/ModBusRtuServerPawn1.zip

Al HMI:

http://slicetex.com/docs/an/an024/files/an024-example1.zip


¿ Al reiniciar los valores de fabrica, el proceso fue completo y todos los leds parpadearon ?.

Gracias y avísame.
« Última Modificación: septiembre 21, 2016, 10:13:03 am por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

guille

  • Novato
  • *
  • Mensajes: 16
Re:Error MODBUS
« Respuesta #2 : septiembre 21, 2016, 12:08:41 pm »
Hola Boris,

gracias por tu pronta respuesta! Te adjunto el proyecto completo. Seguí ambas notas de aplicación (AN023 y 024) para programar el HMI. Esta tarde voy a probar directamente con los proyectos que me enviás.

El proceso de RESET se dio como indicado: presione ambos botones, solté RESET y al cabo de unos segundos parpadeaba PAUSE. Ahi aprete 5 veces DEFBOOT, todos los leds se encendieron y acto seguido quedaron prendidos RUN ERROR y RTC ERROR. Cuando configure el PLC, le puse la hora y le baje un programa, estos se apagaron y todo volvió a la normalidad.

Cuando cargue nuevamente mi programa, el error persistió.

Saludos,

Guillermo.

guille

  • Novato
  • *
  • Mensajes: 16
Re:Error MODBUS
« Respuesta #3 : septiembre 21, 2016, 12:16:15 pm »
Adjunto!

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 1625
  • Soporte Técnico
Re:Error MODBUS
« Respuesta #4 : septiembre 21, 2016, 12:31:49 pm »
Ok, lo pruebo y te aviso.

Estamos en contacto.
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 1625
  • Soporte Técnico
Re:Error MODBUS
« Respuesta #5 : septiembre 21, 2016, 18:10:58 pm »
Buenas tardes Guillermo,

Acabo de probar tu programa y se trata de un error en tu programa, que te detallo a continuación:

Desde tu "loop principal" while() llamas a la instrucción "return 0", lo cual hace que el programa principal del PLC, retorne al sistema operativo del PLC desde la función PlcMain(). Entonces, el sistema operativo del PLC intenta cargar nuevamente el programa tuyo, llamando nuevamente a la función PlcMain(), pero al inicializar la librería ModBus, se encuentra que "ya fue inicializada", por eso te devuelve "-1".

Te señalo en rojo el error del código original:

PlcMain()
{

// ...

while(true)
   {
      // Obtener información del reloj.
      RtcGetAll(Day, Month, Year, Hour, Min, Sec, DOW) //Reg 42010 al 42015
           
      MbRtuServLoadRegister(42010, Day)
      MbRtuServLoadRegister(42011, Month)
      MbRtuServLoadRegister(42012, Year)
      MbRtuServLoadRegister(42013, Hour)
      MbRtuServLoadRegister(42014, Min)
      MbRtuServLoadRegister(42015, Sec)
      //MbRtuServLoadRegister(42017, TiempoUsoHs)

      //Elige programa
      MbRtuServGetRegister(42018, Programa)
     
      //Comprueba si se ha modificado un programa
      MbRtuServGetRegister(42019, Config)
     
      //Iniciar Programa
      MbRtuServGetRegister(42020, Start)
     
      //Guarda las modificaciones realizadas sobre el programa en EEPROM
      if(Config)
         {
               Config=0
               DelayS(2)
               MbRtuServLoadRegister(42019, Config)
               
               MbRtuServGetRegisters(42001,9,A)
               EepromWrite(1,9,A)
               
               MbRtuServLoadRegisters(42001,9, A)
         
         }
   // Retorno.   
   return 0

   }
}

Deberías colocar el return afuera del "loop principal", solo debe llamarse cuando tu programa no se utilice mas, es decir nunca.

La forma correcta es:

PlcMain()
{

// ...

while(true)
   {
      // Obtener información del reloj.
      RtcGetAll(Day, Month, Year, Hour, Min, Sec, DOW) //Reg 42010 al 42015
           
      MbRtuServLoadRegister(42010, Day)
      MbRtuServLoadRegister(42011, Month)
      MbRtuServLoadRegister(42012, Year)
      MbRtuServLoadRegister(42013, Hour)
      MbRtuServLoadRegister(42014, Min)
      MbRtuServLoadRegister(42015, Sec)
      //MbRtuServLoadRegister(42017, TiempoUsoHs)

      //Elige programa
      MbRtuServGetRegister(42018, Programa)
     
      //Comprueba si se ha modificado un programa
      MbRtuServGetRegister(42019, Config)
     
      //Iniciar Programa
      MbRtuServGetRegister(42020, Start)
     
      //Guarda las modificaciones realizadas sobre el programa en EEPROM
      if(Config)
         {
               Config=0
               DelayS(2)
               MbRtuServLoadRegister(42019, Config)
               
               MbRtuServGetRegisters(42001,9,A)
               EepromWrite(1,9,A)
               
               MbRtuServLoadRegisters(42001,9, A)
         
         }
   }

   // Retorno.   
   return 0


}

Luego de ese cambio, el panel HMI y las funciones, se comportan con normalidad.

Quedo a disposición.

Saludos

SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 1625
  • Soporte Técnico
Re:Error MODBUS
« Respuesta #6 : septiembre 21, 2016, 18:20:00 pm »
También te recomiendo en el Loop principal usar un delay, ya que el ciclo while() esta siendo ejecutado a toda la velocidad posible por el procesador del PLC.

Entonces, a veces, para permitir otras operaciones o evitar que por error escribras indefinidamente una memoria EEPROM por ejemplo, o para no sobrecargar al panel HMI con comunicaciones RS232 innecesarias de un mismo valor, se recomienda utilizar un pequeño Delay, el cual debe ser tan pequeño como la respuesta esperada por tu sistema.

Por ejemplo:

while()
{
     // ...
     // Todas tus funciones y operaciones.
     // ...

     // Pausar programa por 250 mS.
     DelayMS(250)

}

Hay ocasiones en que no hace falta, no es obligatorio, pero conviene por ejemplo en tu caso para no sobrecargar el panel HMI con escrituras o lecturas RS232.

Finalemente, si tu programa comienza a crecer, te recomiendo separar el código en funciones y archivos, así luego te es mas fácil comprenderlo y modificarlo, sin tener todo amontonado en una misma función.

Saludos
« Última Modificación: septiembre 21, 2016, 18:26:57 pm por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

guille

  • Novato
  • *
  • Mensajes: 16
Re:Error MODBUS - Solucionado
« Respuesta #7 : septiembre 30, 2016, 11:46:45 am »
Hola Boris,

Puedo darme cuenta de lo que me decis. Problema solucionado!

Gracias!