Dudas con Labview y puerto serial RS-232

Tengo un manual sobre labview he hecho unos de lo ejemplos de puerto serial pero no me comunica.
Tengo el labview 8.6, la pregunta es ase falta instalar los driver ni-visa aparte, o el labview con lo que tiene es suficiente para su funcion con el puerto serial.
 
amigo visa se instala con la instalacion normal de labview , el problema debe estar en otra parte , compartiendo el codigo podriamos ayudarte , saludo s
 
pues amigo el codigo al parecer esta bien , una cosa al seleccionar el visa resourse name te reconoce los puertos de tu pc ( COM ) ah y mirar como estas haciendo la comunicacion con un microcontrolador supongo para mirar depronto el error alli.

saludos .........
 
hola a todos, soy nuevo en labview y en programación ccs, tengo que desarrollar un programa en labview donde dos barras horizontales me generen dos datos cada una respectivamente, esos datos los debo enviar a un dspic 33fj128mc802, por el puerto serie, no se como construir lo necesario en labview (manejando los paquetes de visa) para hacer este proceso y a su vez no se como hace el despic para que reconozca los dos datos enviados simultáneamente, y con los datos enviados me genere dos señales pwm. por su colaboración muchas gracias
 
hola soy nuevo en el uso de labview, lo que quiero realizar es un pequeño "formulario" con varios campos de texto para luego enviarlos por el puerto serie. Lo que no logro entender es como identifico cada dato enviado para que luego lo pueda interpretar en el pic. nose si logro explicarme
 
lo que debes hacer es buscar en la parte grafica una cajita de texto pues los hay numericos y flotantes

pones los que son texto y pisas CONTROL+T t te manda a los iconos de "programacion"
ahi buscas elementos tipo String son los color rosa
los hay para hacer tokens , concatenar , guardar array , leer una letra ,etc.

tu usaras los tipo concatenar y este tipo String buscaras la parte serial es el icono en forma de telefono , no me acuerdo bien como esta esto pues hay que configurar los baudios , error y VISA
que se encarga de acceder al puerto serie

hay ejemplos en internet lamentablemente si buscas ejemplos a verciones superiores de tu labview no podras abrirlos
 
estoy haciendo un control de luminarias mediante horario o para que estas funcionen de manera automatica ( dependiendo si hay luz o no) dependiendo de lo que se escoja en la interfaz de labview, mi problema es que no he podido comunicar el pic con labview (lo probe con puertos virtuales), he hecho tres programas para el pic(16f877a) pero ninguno me funciona:cry: queria perdirles ayuda para solucionar mi problema. adjunto progrma labview, cto en proteus, y los programas para el pic
 

Adjuntos

  • Nueva carpeta (4).rar
    34.8 KB · Visitas: 24
Hola a todos. Estoy tratando de comunicar labview con el pic 16f877a pero el pic no me responde a ninguna orden.
Subo mi programa para ver que me dicen.

Código:
#include <16F877A.h>
#include <stdlib.h>
#use delay(clock = 4000000)      //Cristal de 4 MHz//

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)   //CONFIG USART //

#fuses XT, NOWDT, NOLVP, NOBROWNOUT   //Programación de bits de Configuración//

#byte pa=0x05
#byte pb=0x06
#byte pc=0x07
#byte pd=0x08

 char cadena[3];                  //Guardará el string recibido
int i;                           //Número de caracteres del string
float32 c;                   //Dato recibido en formato float

#int_RDA 

void RDA_isr(){

  cadena[i]=getc();             //Recepción del string          
   ++i;                          //Preparación para recibir el siguiente caracter
   if (i==3) {                   //Todos los caracteres recibidos
      i=0;                       //Preparación para recibir el siguiente string
      c = atof(cadena);      //Paso del string a su valor float
}
//char c;

disable_interrupts(GLOBAL);
//c= getc();

if (c=="BD"){
   printf("%s","escoja tipo de control\r");
   
   
   }
     else if(c=="ACF"){
    
    printf("%s","Orden desconocida\r");
 
}
     else if(c=="AD"){
    
    printf("%s","Control automatico activado\r");
    if (pa==0x01)
{
  pb=0xff;
  }
  else 
{  
  pa==0x00;
   }}
  else if(c=="BCF"){
   
     printf("%s","Cotrol horario activado\r");
     delay_ms(200);
     printf("%s","luminarias apagadas\r");
     
     }
    
    else if(c=="BCE"){
   
  printf("%s","Cotrol horario activado\r");
     delay_ms(200);
     printf("%s","luminarias encendidas\r");
     
   pb=0xff;
  }
    
void main()
{
   set_tris_a (0xff);
   set_tris_b (0x00);
   set_tris_c (0xB8);
   
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
  
   while(1);
   enable_interrupts(GLOBAL);
   }
 
Pues así nunca va a funcionar.
Recibes una cadena que luego no sé porqué motivo conviertes a float de 32 bits y luego la comparas con otra cadena.

Si vas a recibir y comparar cadenas, ¿por qué mejor no usas un método más sencillo?

Algo así pero sin usar interrupción:
Código:
#include <16F877A.h>
#fuses   NOBROWNOUT
#use     delay(crystal = 8MHz)
#use     fast_io(b)
#use     rs232(uart1)

char cadena[4];

void main (void){

   set_tris_b (0b11111100);
   output_b(0x00);
   putc(0x00);
   delay_ms(100);
   
  
   while(true)
   {
         
      gets(cadena);                       // Se recibe la cadena y sale hasta recibir un CR (13)
      
      switch (cadena)                     // Se inicia la comparación.
      {
         case "ABC":                      // ¿Cadena = ABC?
            output_high(pin_b0);          // Si, RB0 en 1
            puts("Activando RB0\r");      // Se notifica.
            break;                        // Sale de la rutina de comparación.
         case "DEF":                      // Se repite.
            output_high(pin_b1);
            puts("Activando RB1\r");
            break;
         case "GHI":
            output_low(pin_b0);
            puts("Desactivando RB0\r");
            break;
         case "JKL":
            output_low(pin_b1);
            puts("Desactivando RB1\r");
            break;
         default:
            puts("Comando desconocido\r");
            break;
      }
   }
}
Este programa funciona, pero tiene el defecto de que al usar gets(); para recibir la cadena, no se retorna hasta que se reciba un retorno de carro (13)

Algo que debes tener en cuenta, es que si la cadena que vas a recibir tiene una longitud de 3 caracteres, entonces el buffer debe tener un byte más, por ejemplo; char cadena[4];

Otro motivo por el cual tu programa no funcionaría, es porque desactivas las interrupciones durante el servicio de interrupción.
Generas un bucle con while(1); y a continuación es dónde las piensas habilitar nuevamente,
pero de ese bucle el programa no pasará y las interrupciones jamás se volverán a habilitar.

Tampoco es recomendable trabajar a 4MHz con una velocidad de 9600bps.
Cuando recibes un byte, por ejemplo "A", entonces puede no haber problemas, pero cuando esperas una cadena, se puede perder información y lo mejor es trabajar con frecuencias más altas o disminuir los baudios.

Me parece que lo más correcto, es que nos expliques qué es lo que deseas hacer con ese programa.

Saludos.

PD:
Yo no uso LabView.
 
hola, te comento que los programas que tienes para ccs picc no andan muy bien que digamos pero quizá este ejemplo pueda guiarte.

Código CCS PicC
Código:
#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PUT                      //Power Up Timer
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading

#use delay(crystal=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_c6,rcv=PIN_c7,bits=8)

char buffer_rx[4];

unsigned int8  banderas;
#bit  buffer_rx_listo=banderas.0
#INT_RDA
void  RDA_isr(void) 
{
   static unsigned int8 n_bytes;
   
   buffer_rx[n_bytes++]=getc();
   if(n_bytes==4)
   {  
      n_bytes=0;
      buffer_rx_listo=1;
   }
}
void main()
{ 
   output_b(0);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      while(!buffer_rx_listo);
      buffer_rx_listo=0;
      if(buffer_rx=="ABC")
      {
         output_a(255);
      }
      switch(buffer_rx)
      {
         case "ABC":
         {
            output_toggle(pin_b0);
            printf("abc");
            break;
         }
         case "DEF":
         {
            output_toggle(pin_b1);
            printf("def");
            break;
         }
         case "GHI":
         {
            output_toggle(pin_b2);
            printf("ghi");
         }
      }
   }
}

Dibujo1.PNG
Dibujo2.PNG

PD. El programa en Labview esta en la version 8.5 asi que no creo que tengas problema para abrirlo.
Para la use un creador de puertos serie virtuales(virtual null modem), los comm sen el 3 para proteus y 4 para labview.
 

Adjuntos

  • labview_serie.rar
    135.7 KB · Visitas: 51
Última edición:
hola de nuevo segui sus consejos y mejore el programa en labview y el del pic, pero aun me da errores :cry:ya nose que hacer :LOL:, si alguien puede revisarlos y aconsejarme lo agradeceria adjunto programas y simulacion
 

Adjuntos

  • Nueva carpeta.rar
    46 KB · Visitas: 14
Hola de nuevo.
Seguí sus consejos y mejoré el programa en labview y el del pic, pero aún me da errores. :cry:
Ya no sé que hacer. Si alguien puede revisarlos y aconsejarme, lo agradecería.
Nop, no pusiste atención sobre lo que te mencioné anteriormente sobre deshabilitar las interrupciones.
Este proceso lo hace el compilador automáticamente.
Si tú las deshabilitas tienes que volverlas a habilitar, pero sigues realizando el mismo proceso.


while(1); <--- Tienes que entender que si haces esto.
enable_interrupts(GLOBAL);
<--- El programa no pasará a esta parte.

Elimina disable_interrupts(GLOBAL); del servicio de interrupción y mira bien los comentarios y los ejemplos expuestos.
 
aqui ay un detalle que creo que muchos no se han percatado

no es problema 100% del pic

mas bien es si tienes un puerto serie virtual o cable USB a serie no se por que demonios el Labview no lo detecta, aveces lo detecta pero no saca nada.

hay que configurar la VISA del labview pero como yo ya estoy retirado del diseño de labview no puedo indagar mas pero es algo que me llego a pasar el programa del pic no jalaba.

lo depure muchas veces con PUTTY hasta que descubri este problema , prueba con una PC que tenga puerto serie real y deberia funcionar ,cosa que ami me paso.

suerte



otra cosa yo trataria de mandar comandos por puerto serie atravez del PUTTY o la hyperterminal
es decir ingresar los comandos o la trama manual mente para ver que el micro responde la trama como queremos.

y por parte del labview ver que la trama la saque eso se hace con un puerto serie virtual y con el Putty conectado al puerto virtual y ver que todo enviamos salga por el PUTTY

como si enchufaramos un cable al COM1 de la PC con el COM2 de la misma PC , PERO! virtualmente.
 
Última edición:
gracias por responder probe labview con hiperterminal y funciona, tambien lo probre con el pic y no me responde ah!! me equivoque al subir el programa del pic es este, pero como ya mencione al probarlo con hiperterminal no recibe nada, al probarlo con labview le llegan los comandos pero no responde, gracias nuevamente por responder y perdon por molestar tanto
Código:
#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PUT                      //Power Up Timer
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading

#use delay(crystal=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_c6,rcv=PIN_c7,bits=8)

char buffer_rx[2];

unsigned int8  banderas;
#bit  buffer_rx_listo=banderas.0
#INT_RDA
void  RDA_isr(void) 
{
   static unsigned int8 n_bytes;
   
   buffer_rx[n_bytes++]=getc();
   if(n_bytes==2)
   {  
      n_bytes=0;
      buffer_rx_listo=1;
   }
}
void main()
{ 
   output_b(0);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      while(!buffer_rx_listo);
      buffer_rx_listo=0;
      if(buffer_rx=="A")
      {
         output_a(255);
      }
      switch(buffer_rx)
      {
         case "A":
         {
         printf("control automatico ");
             if (input(pin_b0)){
    output_high(pin_b1);
    printf("luminaria encendida");}
else{
    output_low(pin_b1);
    printf("luminaria apagada  ");}
            
            break;
         }
         case "B":
         {
         printf("control     horario");
            output_high(pin_b1);
            printf("luminaria encendida");
            break;
         }
         case "C":
         {
         printf("control     horario");
            output_low(pin_b1);
            printf("luminaria   apagada");
         }
      }
   }
}
 
Última edición por un moderador:
Probe labview con hiperterminal y funciona.
También lo probé con el pic y no me responde.

Como ya mencioné, al probarlo con hiperterminal no recibe nada, al probarlo con labview le llegan los comandos pero no responde.
Mira bien lo que está pasando...

Está esta sentencia en el código:
Código:
   [B]if(n_bytes==[COLOR=Green]2[/COLOR])
   {  
      n_bytes=[COLOR=Green]0[/COLOR];
      buffer_rx_listo=[COLOR=Green]1[/COLOR];
   }[/B]
O sea que el buffer con los datos de recepción estará listo hasta que tenga 2 bytes.
Pero ahora estás comparando con un solo byte. --> case "A":

Así que, si quieres comparar una letra nada más, debes cambiar n_bytes == 1
Si quieres recibir 8 bytes; n_bytes == 8 y así...

Entonces así quedaría el programa:
Nota que tiene algunos cambios...
Código:
#include <16f877a.h>
#fuses   nobrownout

#use delay(crystal = 4MHz)
#use rs232(uart1)

char buffer_rx[2];

unsigned int8  banderas;
#bit  buffer_rx_listo=banderas.0

#INT_RDA
void  RDA_isr(void) 
{
   static unsigned int8 n_bytes;
   
   buffer_rx[n_bytes++]=getc();
   if(n_bytes==1)
   {  
      n_bytes=0;
      buffer_rx_listo=1;
   }
}
void main()
{ 
   output_b(0);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   while(TRUE)
   {
      while(!buffer_rx_listo);
      buffer_rx_listo=0;

      switch(buffer_rx)
      {
         case "A":
         {
            output_a(255);
            puts("control automatico\r");
            
            if (input(pin_b0)){
               output_high(pin_b1);
               puts("luminaria encendida\r");}
            else{
               output_low(pin_b1);
               puts("luminaria apagada\r");}
            break;
         }
         case "B":
         {
            puts("control     horario\r");
            output_high(pin_b1);
            puts("luminaria encendida\r");
         break;
         }
         case "C":
         {
            puts("control     horario\r");
            output_low(pin_b1);
            puts("luminaria   apagada\r");
         break;
         }
         default:
         {
            puts("Comando inválido\r");
         }
      }
   }
}
En la imagen adjunta se muestran los resultados.
 

Adjuntos

  • Serial Port Control RC1 (Test).jpg
    Serial Port Control RC1 (Test).jpg
    167 KB · Visitas: 27
Gracias por responder. Arreglé lo que me dijiste y probé nuevamente.
Con el comando puts, el pic me reconoce el dato pero no responde.
Con el comando printf, reconoce el dato pero responde solo una vez y mal.
Por último hice un programa en microcode que me respondió bien pero tuve problemas con labview que aun no resuelvo.

Adjunto imágenes con cada prueba y el código microcode.

Código:
'DEFINE OSC 4
@ DEVICE PIC16F877A
@ DEVICE PROTECT_OFF,CPD_OFF,WDT_OFF,PWRT_ON,BOD_OFF,LVP_OFF

INCLUDE "modedefs.bas" ;incluyen los modos de comunicación


TRISA = $FF
TRISB = $F1
TRISC = $BF
TRISD = $F3

serial VAR BYTE ;variable de almacenamiento de 255

releF VAR portd.2 ;nombres para los pines

led var portd.4
x var byte

entra var portb.0
salida var portb.1
SYMBOL TxD = PORTC.6
SYMBOL RxD = PORTC.7

inicio:
; Inicializar los puertos
    PORTB=$00
    PORTC=TRISC
    PORTD=TRISD
;3 parpadeos del led que indica funciona
    FOR x =1 TO 3
    HIGH led 
    PAUSE 200
    LOW led
    PAUSE 200
    NEXT
     PAUSE 500
recibir:
    SERIN RxD,T9600,serial ; comparar con pruebaredes
    SELECT CASE serial
        CASE "A"    ; A
            GOTO automatico
        CASE "B"    ; B
            GOTO horarioapa
        CASE "C"    ; C
            GOTO horarioenc
             
       CASE ELSE
            SEROUT TxD,T9600,["comando   invalido.",13,10]
    END SELECT
    PAUSE 500   ; Retardo para estabilizar el puerto
    goto recibir

automatico:
     SEROUT TxD,T9600,["control automatico.",13,10]
    if entra=1 then 
     high salida
     SEROUT TxD,T9600,["luminaria encendida",13,10]
      PAUSE 500
     goto recibir
      else
      low salida
       SEROUT TxD,T9600,["luminaria  apagada.",13,10]
        PAUSE 500
    goto recibir
     endif
     
horarioapa:
     SEROUT TxD,T9600,["control    horario.",13,10]
     low salida
      PAUSE 500
        SEROUT TxD,T9600,["luminaria  apagada.",13,10]
         PAUSE 500
    goto recibir

horarioenc:
       SEROUT TxD,T9600,["control    horario.",13,10]
        PAUSE 500
       high salida
        PAUSE 500
     SEROUT TxD,T9600,["luminaria encendida",13,10]


Perdón, pero tengo otra consulta. ¿Está bien controlar la salida como lo puse en el programa?
¿O no se puede controlar así? (En automático y horario)
 

Adjuntos

  • conputs.jpg
    conputs.jpg
    71.5 KB · Visitas: 9
  • conprintf.jpg
    conprintf.jpg
    57.2 KB · Visitas: 6
  • conmicrocode.jpg
    conmicrocode.jpg
    91.7 KB · Visitas: 7
Última edición por un moderador:
En la subrutina "horarioenc" te hace falta un retorno.
Las salidas está bien que las controles así, independientes.

Como ya definiste las salidas con TRISX, también puede ser así; salida = 1 o salida = 0

Si piensas usar RS-232 por software con PICBasic, entonces si te sugiero que subas la frecuencia de trabajo.
O utiliza las rutinas para trabajar con RS-232 por hardware, porque PBP es lento por software.
También trata de no utilizar retardos porque eso hará que se puedan perder datos de recepción.

Por ejemplo, así:
Código:
Define OSC 4
@ Device PIC16F877A
@ Device WDT_OFF, PWRT_ON, BOD_OFF, LVP_OFF

inicio:
    Symbol Entrada  = PORTB.0
    Symbol Salida   = PORTB.1
    Symbol TxD      = PORTC.6
    Symbol RxD      = PORTC.7
    Symbol LED      = PORTD.4
    
    Serial  Var Byte         ; Variable de almacenamiento.
    x       Var Byte
; Inicializar los puertos
    TRISB = $F1
    TRISC = $BF
    TRISD = $F3
    
    PORTB = 0
    PORTC = TRISC
    PORTD = TRISD
    
; Configuración USART: (9600bps @ 4MHz. 9615bps reales, 0.16% de error.)
    SPBRG =    25    ; 00011001
    TXSTA =    36    ; 00100100
    RCSTA =    144    ; 10010000
    
; 3 parpadeos del led para indicar que funciona.
    For x = 1 To 3
        Toggle LED
        Pause 200
    Next x
        
    HSerOut [0]                 ; Inicializar el bus RS-232
    
    Pause 100
    
Recibir:
    HSerIn 100,Salir,[Serial]   ; Recibir los datos.
    
    Select Case Serial
        Case "A"    ; A
            GoSub Automatico
        Case "B"    ; B
            GoSub Horario_Apagado
        Case "C"    ; C
            GoSub Horario_Encendido
             
       Case Else
            HSerOut ["Comando inválido.",13,10]
    End Select
Salir:
    GoTo Recibir

Automatico:
    HSerOut ["Control automático.",13,10]
    If Entrada = 1 Then 
        Salida = 1
        HSerOut ["Luminaria encendida.",13,10]
        Return
    Else
        Salida = 0
        HSerOut ["Luminaria apagada.",13,10]
        Return
    EndIf
     
Horario_Apagado:
    Salida = 0
    HSerOut ["Control horario.",13,10]
    HSerOut ["Luminaria apagada.",13,10]
    Return

Horario_Encendido:
    Salida = 1
    HSerOut ["Control horario.",13,10]
    HSerOut ["Luminaria encendida",13,10]
    Return
     
    End

Suerte.
 
Última edición:
@panchoreyes, te comento que el programa que subiste el el post 15 si funcionaria asumiendo el caso de que labview enviara la cadena de texto "A" (caracter 'A' + 0x00) y asi se arian los dos bytes ya que cuando se comparan cadenas de texto el compilador C las compara caracter a caracter hasta que encuentra el "caracter NULL(0x00)" y luego termina la comparacion. Si labview solo envia un caravter 'A' entonces el programa no funcionaria correctamente.

El programa que subio D@rkbytes en el post 16 tambien funciona correctamente solo que labview tendria que guardar los bytes en un vector, cadena de texto o similar hasta encontrar el retorno de carro('\r') y solamente despues de eso mostrar el mensaje..., es decir que a parte de ver el codigo del pic tambien har que ver el programa en labview solo asi se podra ver donde esta el problema ya que por lo que veo el problema real esta en como es que labview esta tratando los datos que recive.

Respecto al ultimo programa que subiste tambien deberia funcionar solo que no quedo "muy bonito" que digamos pero igual funciona solo que te falto una ultima linea de codigo que tambien es un "goto recibir"...
Una limitante que hay para ayudarte por ahora es no podemos ver tu prgrama en labview o almenos yo no puedo ya que tengo la vercion 8.5 y no puedo abrir el programa que subiste y por tanto no puedo recomendarte mayores soluciones.

que tal si subes tu programa de labview pero con compatibilidad a verciones anteriores o por lo menos una imagen de diagrama de bloques y panel frontal.
 
gracias por responder, ahora el error que me lo da labview presiono el boton automatico y no tengo problemas la transmision y recepcion de datos da bien, pero al presionar el boton horario se para la aplicacion enviandome un mensaje, subrayando visa read y obligandome a parar la aplicacion. subo imagen de error, programa labview version 8.5 y cto en proteus. lo estoy simulando con virtual serial port driver. Saint_ el programa en el comentario 15 no me funciono con el unico que tuve mas resultados fue con el ultimo que lo hice en microcode
 

Adjuntos

  • labviewserie Folder.rar
    67.2 KB · Visitas: 13
Atrás
Arriba