Recepción de datos por usb y envío a un socket UDP CCS

Buenas,

La finalidad del programa consiste en recibir datos constantemente por usb, paquetes de 64 bytes y enviarlos a un socket udp, tengo el programa en labview que envía 64 bytes por usb y también puedo recibir por usb mensajes para seguir el programa que se está ejecutando en el pic. Y para ver los datos que envío por udp, abro en el hércules la comunicación udp.

Utilizo el stack TCP/IP de microchip y mi código para grabar en el pic es el siguiente:

Código:
#include "config18F67J50Trainer.c"

#define  STACK_USE_MCPENC      TRUE
#define STACK_USE_ICMP         TRUE
#define STACK_USE_ARP          TRUE
#define  STACK_USE_UDP         TRUE

#include "tcpip/stacktsk.c"
#include "usb/usb_cdc.h"

#include "usb/usb_bootloader.h"




int8 buffer[64]={0}; //defino un buffer de 64 bytes donde guardo los datos que llegan por usb

int8 contador=0;


NODE_INFO udp_info; // node_info es una estructura que tiene MAC e IP
UDP_SOCKET s;

void IP_ADDR (void)   /*aquí escribo la IP de destino, que corresponde a la de mi PC
                     y es la  dirección IP que pongo en el hércules para abrir la conexión UDP*/
  {
   udp_info.IPAddr.v[0]=192;
   udp_info.IPAddr.v[1]=168;
   udp_info.IPAddr.v[2]=2;
   udp_info.IPAddr.v[3]=100;
   }

void MAC_ADDR (void) /*la MAC está en blanco, lo he puesto así porque lo he visto
                               en los ejemplos y creo que es para el envío broadcast*/
{
   udp_info.MACAddr.v[0]=0xFF; 
   udp_info.MACAddr.v[1]=0xFF;
   udp_info.MACAddr.v[2]=0xFF;
   udp_info.MACAddr.v[3]=0xFF;
   udp_info.MACAddr.v[4]=0xFF;
   udp_info.MACAddr.v[5]=0xFF;
}
  


void envio_datos(void)  // esta función será llamada en el main
{
   int8 TMPC; //defino  una variable intermedia
   int8 cont=0;
   printf(usb_cdc_putc, "Comienza envío de datos UDP");
   for(cont=0;cont<=63;cont++)
   {
      if (UDPIsPutReady(s))
                    {                   
                    output_toggle(LedR); /*cambio los leds para detectar el envio
                                                   de datos en la  placa*/
                    output_toggle(LedV);
                     TMPC=buffer[cont];
                     UDPPut(TMPC);
                     printf(UDPPut, "%i", TMPC); /*no sé cual de las dos instrucciones me sirve 
                                                           realmente para ver los datos que envío, no sé 
                                                            bien la diferencia entre ambas, he probado a 
                                                             poner las dos para asegurar que se envían los 
                                                           datos, si alguien sabe la diferencia lo agradecería*/
                      
                    delay_ms(100);
                    }
      
   }  
   UDPFlush(); //envío los datos que están en el buffer de transmisión
   printf(usb_cdc_putc, "64 bytes enviados");
   contador=0;
} 

void main (void)
{
   ON(LedR);
   OFF(LedV);
   
   usb_cdc_init();
   usb_init();
   usb_wait_for_enumeration();
   
   void IP_ADDR();
   void MAC_ADDR();
   
   
   StackInit();
   printf(usb_cdc_putc, "Inicializado UDP");
      
   
   ON(LedV);
   OFF(LedR);   
   
   s=UDPOpen(1234, &udp_info, 2345);/*abro el socket s, 1234 es el puerto de origen
                                                       y 2345 el puesto de destino, la información de 
                                                   udp_info es la del nodo remoto, es decir en este 
                                                    caso la IP de mi ordenador que es adonde quiero 
                                                       enviar los datos*/
   printf(usb_cdc_putc, "Abierto socket UDP");
       
   if (s !=INVALID_UDP_SOCKET)
   {
      printf(usb_cdc_putc, "Socket UDP válido");
      while(TRUE)
      {
            StackTask();
            buffer[contador]= usb_cdc_getc();
            contador++;
            if (contador>=63) envio_datos();
      }
   }   
   
   printf(usb_cdc_putc, "Socket UDP no válido");
   UDPClose(s);
   printf(usb_cdc_putc, "Cerrado socket UDP");
}



el fichero de configuración de la entrenadora es:

Código:
#include <18F67J50.h>
#fuses HS_PLL,NOWDT,NOXINST,STVREN,NOPROTECT,FCMEN,NODEBUG,PLL2,NOCPUDIV,MSSPMSK7,IESO
#use delay(clock=48000000)

#bit PLLEN = 0xf9b.6

#define  ON    output_high
#define  OFF   output_low

// Connections in 18F67J50Trainer
#define  LedV     PIN_G0
#define  LedR     PIN_G1

// Connections between ModEthernet and 18F67J50Trainer
#define  PIN_ENC_MAC_CS    PIN_D0
#define  PIN_ENC_MAC_RST   PIN_D1
#define  PIN_ENC_MAC_INT   PIN_D2
#define  PIN_ENC_MAC_WOL   PIN_D3
#define  PIN_ENC_MAC_SI    PIN_D4   // MISO: PIC > ENC
#define  PIN_ENC_MAC_SO    PIN_D5   // MOSI: PIC < ENC
#define  PIN_ENC_MAC_CLK   PIN_D6   // SCK



He buscado ejemplos de envío de paquetes de Udp, las funciones de UDP son bastante sencillas, pero hay algún problema en el programa porque al ejecutarlo leo en labview "comienza el envío de datos" y "64 bytes enviados" continuamente, y los leds también se encienden y se apagan.


Las conexiones entre la tarjeta enc28j60 y mi pic 18f67j50 están correctas, el módulo donde tengo la enc28j60 está conectado al router de mi red, pero en el programa de recepción UDP no leo absolutamente nada. El puerto fuente del código es el que pongo como puerto de destino en hércules y viceversa, he probado a poner la MAC de mi ordenador tambien, y tambien he probado con IP 255.255.255.255 para hacer un envío broadcast y no consigo recibir absolutamente nada, no tengo antivirus activos en mi ordenador, y la verdad no sé dónde está el problema del programa ni que más puedo revisar, si alguien tiene alguna idea o detecta algún error en el código o en la configuración de la IP o MAC se lo agradecería.


gracias por su tiempo, saludos!
 
Bueno, encontré el problema del código, para empezar es necesaria asignar una MAC que corresponda con la del fabricante a la tarjeta de red que estamos usando y asignar también una IP libre dentro de la red local, y por otro lado tendremos otra MAC y otra IP que sí que se corresponderán con el nodo al que le envíamos los datos, o podemos ponerlo todo a 1 para hacer broadcast según nos interese.
 
Hola clematida, te escribo para solicitarte ayuda respecto al envio de datos al socket UDP. Tengo un error al complilar en la siguiente instrucción:
s=UDPOpen(1100, &info_remota, 2500);

Me dice que debe aparecer una expresión númerica y de verdad no entiendo por que:

Como ya a ti te compiló el código sería buenisimo que me echaras una manito.

gracias:.
 
si, efectivamente lo hice y siempre dice lo mismo al compilar." s "es el socket e info_remota es la estructura que contiene las direcciones MAC e IP remotas. Estuve observando el código que colocaste cuando tenias el error y esta casi igual.



de verdad que no tengo idea de porque sucede eso. Clematida de verdad te agradecería toda la vida si me ayudas en esto, ya que es parte del desarrollo de mi tesis en la universidad. Si tienes algún enlace de donde descargar el stack tcp-ip para ccs, sería bueno. Ahorita estoy intentando compilar el stack tcp-ip de microchip por primera vez y me he visto en serios problemas.. bueno agradezco tu respuesta....
 
Última edición:
yo estuve probando el stack de tcp/ip modificado de ccs y no me gustó porque tuve muchos problemas para independizar el software del hardware porque lo tiene definido en muchos subarchivos, no sé qué micro y que controlador de ethernet usas tú pero yo de ti usaría el stack de microchip sin la modificacion para ccs, en cuanto a donde te lo puedes descargar creo que esta facilmente disponible por la red... ahora mismo no te sé decir pero si tienes problemas cuando tenga algo de timepo te lo miro.

pon el código de las definiciones que has hecho y eso porque solo con esa linea de código es imposible averiguar el problema
 
//AQUI ESTÁ EL CÓDIGO; ES PRACTICAMENTE IGUAL AL TUYO; YA QUE HA SIDO MI GUÍA DE REFERENCIA..
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <18f4550.h>
#fuses XT,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#use delay(clock=4000000)


// Conexión entre el PIC18F4550 y el Modulo ENC28J60 (Se conecta directamente sin adaptador de voltajes).


#define ON output_high //SE DEFINE ESTADO ALTO COMO ON
#define OFF output_low //SE DEFINE ESTADO BAJO COMO OFF

#define LedR PIN_B4 //SE DEFINE LED ROJO EN EL PIN RB4



#define PIN_ENC_MAC_SO PIN_C7 // Conectar con PIN MISO del ENC28J60.
#define PIN_ENC_MAC_SI PIN_B0 // Conectar con PIN MOSI del ENC28J60.
#define PIN_ENC_MAC_CLK PIN_B1 // Conectar con PIN SCK del ENC28J60.
#define PIN_ENC_MAC_CS PIN_B3 // Conectar con PIN CS del ENC28J60.
#define PIN_ENC_MAC_RST PIN_B5 // Conectar con PIN RST del ENC28J60.

#define PIN_ENC_MAC_INT PIN_D2 // Conectar con PIN INT del ENC28J60.
#define PIN_ENC_MAC_WOL PIN_D3 // Conectar con PIN WOL del ENC28J60.




//Protocolos a utilizar.

#define STACK_USE_MCPENC TRUE
#define STACK_USE_ARP TRUE
#define STACK_USE_ICMP TRUE
#define STACK_USE_UDP TRUE


#include "tcpip/stacktsk.c"

NODE_INFO inforemota; //nombre nuevo de la estructura NODE_INFO
UDP_SOCKET s; //define el socket s


void MAC_REMOTA (void) //MAC DE MI PC= 00 19 66 16 CF 26
{

inforemota.MACAddr.v[0]=0x00;
inforemota.MACAddr.v[1]=0x19;
inforemota.MACAddr.v[2]=0x66;
inforemota.MACAddr.v[3]=0x16;
inforemota.MACAddr.v[4]=0xCF;
inforemota.MACAddr.v[5]=0x26;

}

void IP_REMOTA (void) //*aquí escribo la IP de destino, que corresponde a la de mi PC

{
inforemota.IPAddr.v[0]=192;
inforemota.IPAddr.v[1]=168;
inforemota.IPAddr.v[2]=1;
inforemota.IPAddr.v[3]=111;


}


// Microchip VendorID, MAC: 00-04-A3-XX-XX-XX
void MACAddrInit(void) //SE DEFINE MAC DEL DISPOSITIVO
{
MY_MAC_BYTE1=0x00;
MY_MAC_BYTE2=0x04;
MY_MAC_BYTE3=0xA3;
MY_MAC_BYTE4=0x00;
MY_MAC_BYTE5=0x00;
MY_MAC_BYTE6=0x01;
}

void IPAddrInit(void) //SE DEFINE LA IP del PIC
{
//Direccion IP
MY_IP_BYTE1=192;
MY_IP_BYTE2=168;
MY_IP_BYTE3=1;
MY_IP_BYTE4=111;

//Mascara de Subred //SE DEFINE LA MÁSCARA DE SUB RED
MY_MASK_BYTE1=255;
MY_MASK_BYTE2=255;
MY_MASK_BYTE3=255;
MY_MASK_BYTE4=0;

//Puerta de Enlace //SE DEFINE EL GATEWAY O PUERTA DE ENLACE
MY_GATE_BYTE1=192;
MY_GATE_BYTE2=168;
MY_GATE_BYTE3=0;
MY_GATE_BYTE4=1;
}

void envio_datos(void) // esta función será llamada en el main
{

int8 Dato; //defino una variable intermedia

{
if (UDPIsPutReady(s))
{
OFF(LedR); /*cambio los leds para detectar el envio
de datos en la placa*/
delay_ms(500);
Dato=0xff;
UDPPut(Dato);

//printf(UDPPut, "%i", TMPC); /*no sé cual de las dos instrucciones me sirve
// realmente para ver los datos que envío, no sé
//bien la diferencia entre ambas, he probado a
// poner las dos para asegurar que se envían los
//datos, si alguien sabe la diferencia lo agradecería*/

delay_ms(100);
}

}
UDPFlush(); //envío los datos que están en el buffer de transmisión
ON(LedR);
}


void main(void) //FUNCIÓN PRINCIPAL
{


OFF(LedR); //APAGA EL LED ROJO

MAC_REMOTA();
IP_REMOTA();
MACAddrInit(); //CARGA EL VALOR DE LA MAC
IPAddrInit(); //CARGA EL VALOR DE LA IP


ON(LedR); //ENCIENDE EL LED ROJO
delay_ms(1000); //DURANTE 1 SEG
OFF(LedR); //APAGALO
delay_ms(1000); //DURANTE 1 SEGUNDO
ON(LedR); //VUELVE A ENCENDERLO
delay_ms(1000); //DURANTE OTRO SEGUNDO
OFF(LedR); //VUELVE A APAGARLO
delay_ms(1000); //DURANTE OTRO SEGUNDO
ON(LedR);

StackInit(); //INICIALIZA LA PILA

//ENCIENDELO INDEFINIDAMENTE

s=UDPOpen( 1234, &inforemota, 2345);


if (s !=INVALID_UDP_SOCKET)
{

while(TRUE)
{
StackTask();
envio_datos();
}
}


UDPClose(s);

}


/////////ECHALE UN VISTAZO A VER/////////////////



Tengo un error en la ip de mi pc, es 192.168.1.110 pero igual eso no cambia elproblema que tengo.
 
Última edición:
a mi me compila sin problemas tu código, yo uso el PIC C Compiler, es posible que el problema no esté en el código sino en alguna de las opciones del compilador o algo, de todas formas ya lo que no sé es si el código funcionaría en un PIC aunque compile :LOL:
 
bUENO YO ESTOY USANDO EL PIC18F4550 Y EL ENC28J60; EL CÓDIGO SIN EL PROTOCLO UDP ACTIVADO FUNCIONA PERFECTAMENTE Y MI HARWARE ESTÁ PERFECTO PORQUE YA HICE PING. EL PROBLEMA SE GENER ACUANDO LE AGREGO EL PROTOCOLO UDP Y ME GENERA ESE ERROR. SI A TI TE COMPILÓ ENTONCES QUE PODRÁ SER, DE VERDAD NO ENTIENDO. SERÁ QUE ME PUEDES ENVIAR A MI CORREO LA CARPETA TCP-IP QUE USASTES PARA COMPILAR, PROBABLEMENTE AHI ESTE EL ERROR; ESTE ES MI CORREO Hecucent5@yahoo.es.
 
Clematida, te escribo para informarte que ya encontré el error y ya me compiló perfectamente. Tenía un problema con la carpeta TcP-ip donde tenía alojados mis archivos .C y .h, la sustití por laoríginal que tenía guardada y listo. Probablemente haya hecho alguna modificación rara sin querer o se había dañado. Bueno hice la prueba con el hercules y recibo el dao que envio perfectamente. La respuesta de ping también funciona satisfactoriamente. Bueno ahora voy a desarrollar más mi código de tal forma de que reciba datos via UDP y tome decisiones. Cualquier duda estaré escribiendote. Gracias....
 
Que tal clematida; de nuevo te escribo despuÉs de varios dÍas para solicitarte ayuda a ver si puedes. Como sabes luego de enviar datos satisfactoriamente ahora quiero recibir datos via udp pero tengo un problema muy grande y ya tengo varios dias en lo mismo. Lo que pasa es que estoy enviando datos con visual basic 6.0 vÍa udp al pic pero una vez que llegan, el pic no los interpreta como debe ser, es decir, estoy recibiendo pero no exactamente el dato que le estoy enviando. Tienes idea alguna de que pueda ser??? Si es necesario me avisas para colocar el cÓdigo de visual basic y el del pic. Espero tu pronta respuesta.
 
Estás usando dos terminales de comunicaciones en los que tienes un código que no sabes si funciona, para localizar el problema usa un tercer terminal de comunicaciones como el hercules o algún otro en el que tú no tengas que escribir un código para la comunicación, y prueba con uno y otro código a ver en qué parte de la comunicación está el error: en el envío o en la recepción. Lo de no recibir el dato que envías puede ser por el formato en el que estés enviando los datos, decimal, hexadecimal, modo caracter..... o un problema del código, también puede ser que se envíen datos que ya estén en el buffer. En cualquier caso, siempre que tengas que realizar una comunicación y no sabes si el problema está en el código de envío o en el de recepción prueba con otro terminal de comunicaciones más simple y que no requiera programación, prueba a cambiar la visualización de los datos, etc...

Cuéntame si consigues solucionar algo con eso.
 
Que tal Clematida. Ya yo probé con la recomendación que me hiciste antes de que me lo dijeras y realmente estoy casi convencido que el problema es en el codigo de recepción del pic. Te explico, cuando envío por ejemplo el dato 100(en decimal) desde el pic al socket UDP, el hercules me recibe el mismo dato que le envio. Eso esta perfecto. Ahora cuando realizo el proceso contrario; el pic no me reconoce el dato. En esta oportunidad envio el dato 100 (en decimal) desde el hercules y el pic reconoce cualquier otro dato menos ese, y asi me pasa con cualquier dato que envio; ah y si lo envio con el visual basic tambien pasa lo mismo. Fijate lo que he pensado; yo creo que el pic no me está reconociendo el dato porque no he descartado la trama ethernet ni he tomado la sección de datos UDP del paquete. Aja pero esa es mi confusión; la función UDP get(dato) retorna un valor verdadero cuando un byte es leido, luego se procesa y luego se aplica UDP discard para descartar el contenido del buffer y liberalo. Eso es lo que hago y nada;ahora me pregunto; será que es necesario aplicar la función UDP procces para obtener el dato real, o simplemente con UDP get ya lo tengo?. Agradecería tu ayuda, es practicamente lo único que me falta para armar mi sistema.
 
Para saber lo que recibes en el pic tienes que reenviar el dato que recibes del pic, no me queda claro qué pruebas son las que has realizado, ni si has probado a cambiar la visualización de los datos, de todas formas escribe el código del pic pero concreta más los ensayos realizados.

Con la función get de UDP es suficiente para recibir los datos.
 
clematida, por fin resolví el problema lo que pasaba era lo siguiente:
No estaba colocando el simbolo de puntero a mi variable y por lo tanto no accedía a la posición de memoria donde quedaba almacenado el dato.

Yo estaba realizando lo siguiente:

while UDP(Put(Buffer))

{ delay_ms(10);


Dato=Buffer;

UDPDiscard();

}

y me faltaba colocarle el signo de puntero a la variable buffer para que me tomara el byte que recibia. y asi quedó.

while UDP(Put(Buffer))

{ delay_ms(10);


Dato=*Buffer;

UDPDiscard();

}

Ese era todo el problema, ya probé con hercules y visual basic y funciona perfecto. Bueno ahora me toca fajarme duro a armar la estructura de mi proyecto. GRACIAS una Vez más por tu ayuda: Cualquier novedad estaré informandote.....
EXITO!!!

frase:
si entiendes el concepto, serás capaz de entenderlo todo!!

gracias hermano.........



ahh me equivoque en la colocación del segmento de código, realmente es UDPGet..
 
Última edición:
Que tal hermano , estoy pasando por un momento realmente molestoso en mi proyecto. Lo que sucede es lo siguiente: Mi hardware funciona perfectamente en el protoboard pero cuando lo paso a el diseÑo en pcb, no lo hace. He realizado 4 placas diferentes con las conexiones necesarias que lleva el enc28j60 para funcionar pero aÚn no consigo que funcione. Lo mas raro de todo es que pruebo mi circuito en el protoboard y lo sustituyo con el pcb y nada, es decir tengo armado el mismo circuito en el pcb y en el protoboard y uno funciona y el otro no. AgradecerÍa si me puedes ayudar. He revisado la continuidad de las pistas, el valor de los capacitores, las tensiones y nada. Estoy pensando en fenomenos inductivos o capacitivos que alteran mi seÑal pero realmente no se porque no sucede el mismo problema en el protoboard. Gracias de antemano.......ayuda por favor!!!!!!!



Que tal hermano, estoy pasando por un momento realmente molestoso en mi proyecto. Lo que sucede es lo siguiente: Mi hardware funciona perfectamente en el protoboard pero cuando lo paso a el diseÑo en pcb, no lo hace. He realizado 4 placas diferentes con las conexiones necesarias que lleva el enc28j60 para funcionar pero aÚn no consigo que funcione. Lo mas raro de todo es que pruebo mi circuito en el protoboard y lo sustituyo con el pcb y nada, es decir tengo armado el mismo circuito en el pcb y en el protoboard y uno funciona y el otro no. AgradecerÍa si me puedieses ayudar. He revisado la continuidad de las pistas, el valor de los capacitores, las tensiones y nada. Estoy pensando en fenomenos inductivos o capacitivos que alteran mi seÑal pero realmente no se porque no sucede el mismo problema en el protoboard. Gracias de antemano.......ayuda por favor!!!!!!!
 
Última edición:
Luego de bastante tiempo, olvidé colocar la solución del último problema que presenté en armar el proyecto. Por eso retomo y cuento mi experiencia.. Lo que pasaba es que todas las placas que realizé fueron sin la utilización de PLANO DE MASA o tierra, por lo que los datos no eran interpretados correctamente por el Pic.. Ese era todo el problema, asi que mi consejo para cualquiera, es que realizen el diseño de sus placas de montaje electrónico con plano de masa ya que si no, podría verse en serios problemas y situaciones incomodas que hacen perder tiempo y dinero. Esto se aplica sobre todo cuando trabajamos con datos y señales que necesitamos analizar, cuando se trate de pura potencia o circuitos muy simples, quizas no sea necesario, pero vuelvo e insisto, mi recomendación es la utilización del PLaNO DE MASA siempre.. Saludos amigos del foro
 
Última edición:
Atrás
Arriba