Envío de datos por el puerto serie

  • 7 Respuestas
  • 4933 Vistas

MarianoC

  • Aprendiz
  • **
  • Mensajes: 61
Envío de datos por el puerto serie
« : abril 01, 2014, 14:40:06 pm »
Buenas tardes, les cuento que estoy desarrollando un programa que de acuerdo a un valor de tensión que leo en una entrada analógica mando un carácter por el pin Tx del puerto serie a otro dispositivo para que el mismo muestre el estado de carga actual de una batería, uno de los inconvenientes que estoy teniendo es que en el display solo me muestra "LcdPrint(1,0,"Bateria 100%")" cuando también debería mostrarme en la otra fila de dicho display el valor de tensión que esta leyendo en la entrada analógica "LcdPrintf(0,1,"VIN1=%02.2f",Voltaje) ", además de tildarse el microcontrolador no pudiendo sobrescribir otro programa y debiendo resetear la placa volviendo a los valores de fábrica .Luego de la instrucción LcdPrint(1,0,"Bateria 100%") sigue esta función SerialSendByte('A'), el otro dispositivo al cual está conectada la placa plc interpreta que la batería esta al 100%, por ejemplo, si el carácter es B la batería esta al 90% y así sucesivamente .Cuando comento la funcion "//SerialSendByte('A')" el programa anda perfecto.Mi pregunta es, la placa espera una respuesta de parte del dispositivo como un acknowledgement para que esta continúe con la ejecución del programa?.
A continuación les paso el programa.
Código: [Seleccionar]
PlcMain()
{
    // Aqui puede escribir codigo PAWN y llamar a otras funciones.
new Float: Voltaje=0

LcdClear()
VinJumper5UnSet()
RelayClose(RELAY8)
RelayClose(RELAY7)
RelayClose(RELAY6)
RelayClose(RELAY5)
RelayClose(RELAY4)
LcdPrint(1,0,"Bateria 100%")    //en el display me mostraba solo este comentario y no la tensión de entrada luego de poner la siguiente linea
//SerialSendByte('A')               // de envío de un caracter


   for(;;)
   {  Voltaje= Float: VinReadVolt(1)
 
  LcdPrintf(0,1,"VIN1=%02.2f",Voltaje)   //este comentario también debería mostrarme  
  DelayMS(300)
  if((Voltaje<=9) && (Voltaje>8))
  {  RelayOpen(RELAY8)
     LcdClear()
     LcdPrint(1,0,"Bateria 90%")
 DelayMS(300)
 //SerialSendByte('B')
  }  
   if((Voltaje<=8) && (Voltaje>7))
{ RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 80%")
 DelayMS(300)
 //SerialSendByte('C')
}
   if((Voltaje<=7) && (Voltaje>6))
{// RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 70%")
 DelayMS(300)
 //SerialSendByte('D')
}
 if((Voltaje<=6) && (Voltaje>5))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 60%")
 DelayMS(300)
 //SerialSendByte('E')
}
 if((Voltaje<=5) && (Voltaje>4))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 50%")
 DelayMS(300)
 //SerialSendByte('F')
}
if((Voltaje<=4) && (Voltaje>3))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 40%")
 DelayMS(300)
 //SerialSendByte('G')
}
if((Voltaje<=3) && (Voltaje>2))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 30%")
 DelayMS(300)
 //SerialSendByte('H')
}
if((Voltaje<=2) && (Voltaje>1))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 20%")
 DelayMS(300)
 //SerialSendByte('I')
}
if((Voltaje<=1) && (Voltaje>0.5))
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 10%")
 DelayMS(300)
 //SerialSendByte('J')
}
if(Voltaje<=0.5)
{ //RelayOpen(RELAY7)
  LcdClear()
         LcdPrint(1,0,"Bateria 00%")
 DelayMS(300)
 //SerialSendByte('K')
}
   
      // Loop principal.
 
   }

   // Retorno.
   return 0
}
   
Muchas Gracias.
Saludos.
Mariano Campos.
« Última Modificación: abril 01, 2014, 14:48:42 pm por Soporte »

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2313
  • Soporte Técnico
Re: Envío de datos por el puerto serie
« Respuesta #1 : abril 01, 2014, 16:01:50 pm »
Buenas tardes Mariano,

El error se debe a que no estas aplicando correctamente la teoria de funcionamiento del puerto serie.

El puerto serie debe ser inicializado primero con la funcion SerialInit() como describe el manual STX8081-MP-PLC-AX_CX_DX.pdf en pagina 171.

Antes de llamar a cualquier otra funcion del puerto serie, debes inicializarlo, y especificar la velocidad del mismo, por ejemplo:

SerialInit(9600)

Inicializa el puerto serie para una velocidad de 9600 bits-por-segundo.
El dispositivo que conectes, tambien debe usar la misma velocidad para que se entiendan.
Esa instruccion debes colocarla al inicio del programa.

El formato por defecto es 8N1 (8 bits de datos, paridad None, 1 bit de stop), asegurate que tambien que el otro dispositivo (por ejemplo
una PC) use el mismo formato y velocidad que el PLC, asi se "entienden" al intercambiar datos.


El PLC no espera ningun acknoledge al enviar un dato como consultas.

El tema de la impresion del LCD aparenta estar bien, pero al no inicializar correctamente el puerto serie, el funcionamiento
es erratico cuando llamas a las otras funciones que puerto y el CPU del PLC bloquea todas la operaciones, hasta que borres
el programa instalado reiniciando los parametros a fabrica.

Inicializa primero el puerto serie como te dije y avisame si continuas con errores.

Quedo atento a tu respuesta.
« Última Modificación: abril 01, 2014, 16:55:51 pm por Soporte »
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

MarianoC

  • Aprendiz
  • **
  • Mensajes: 61
Re: Envío de datos por el puerto serie
« Respuesta #2 : abril 01, 2014, 16:35:12 pm »
Daba por hecho que lo había inicializado al puerto serie, sin verificar luego si esa instrucción estaba escrita en el código..
Problema solucionado
Disculpas error mio... :-\
Muchas Gracias
Saludos
Mariano Campos.

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2313
  • Soporte Técnico
Re: Envío de datos por el puerto serie
« Respuesta #3 : abril 01, 2014, 17:03:03 pm »
Ningun problema, en buena hora que este solucionado, quedo a disposicion por cualquier otra consulta.
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

MarianoC

  • Aprendiz
  • **
  • Mensajes: 61
Re: Envío de datos por el puerto serie
« Respuesta #4 : noviembre 26, 2014, 14:00:02 pm »
Buenas tardes, les quiero realizar una consulta en relación al puerto serie.
Desde una aplicación android que contiene un control que se denomina SeeKbar el cual varia de 0 a 100, similar al trackbar del virtualhmi, le envió al puerto serie de la placa estos valores por los que puede oscilar dicho control. Cdo varío a una velocidad razonable esto valores se imprimen en pantalla, pero cdo lo hago variar muy rápidamente me imprime solo 10 valores como máximo.
Mi pregunta es, puede ser que los datos no se estén encolando bien?.
Adjunto una porción de código que escribí para visualizar los datos recibidos por puerto serie. 
for(;;)
   {   while((Rx=SerialGetByte())!=-1)
      {    
                            BitClr(Rx,7)
                            NetHmiLcdPrintf(0, 4, LCDSTRING_OPT_NONE,"Pulsos restantes= %d",Rx)
                            DelayMS(500)
      }   
}                     
 

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2313
  • Soporte Técnico
Re: Envío de datos por el puerto serie
« Respuesta #5 : noviembre 26, 2014, 15:24:59 pm »
Mmm se me ocurre que no los estas procesando de forma optimizada y perdes mucho
tiempo con el DelayMS(). Por lo tanto se sobrescribe el buffer de recepción antes de que muestres todo.

Proba:

Código: [Seleccionar]

for(;;)
{
      while((Rx = SerialGetByteTO(500/TICK_RATE_MS)) != -1)
      {   
           BitClr(Rx,7)
           NetHmiLcdPrintf(0, 4, LCDSTRING_OPT_CLRLINE, "Pulsos restantes= %d", Rx)
      }   
}   


Fíjate que también en NetHmiLcdPrintf() limpio la linea antes de imprimir para que no se superpongan valores.

Finalmente SerialGetByteTO() espera en este caso 500 mS antes de retornar (bloquea ejecución), pero
no se utiliza el DelayMS(). Retorna inmediatamente si recibe un byte.

Otra forma es utilizando eventos.
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com

MarianoC

  • Aprendiz
  • **
  • Mensajes: 61
Re: Envío de datos por el puerto serie
« Respuesta #6 : noviembre 26, 2014, 16:40:45 pm »
Entonces TICK_RATE_MS=1 mseg? que es la base de tiempo del contador interno del plc

Soporte

  • Global Moderator
  • Experto
  • *****
  • Mensajes: 2313
  • Soporte Técnico
Re: Envío de datos por el puerto serie
« Respuesta #7 : noviembre 26, 2014, 19:24:20 pm »
Fijate en descripcion de funcion SerialGetByteTO() en pagina 175 del manual de usuario Pawn:

El argumento de la función acepta un Timeout, que se cuenta en TICKs, con una resolución de TICK_RATE_MS.

Que por lo general es de 10 mS.

Si queres 500 mS, debes hacer: 500 / TICK_RATE_MS.
SOPORTE TÉCNICO

Slicetex Electronics
www.slicetex.com