Autor Tema: W5500 servidor por ethernet  (Leído 1426 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
W5500 servidor por ethernet
« en: 23 de Junio de 2020, 07:23:29 »
Hola.

Dispongo de un proyecto que tiene un chip wiznet W5500, el cual sirve como servidor de un sistema, nada del otro mundo, leer algunos datos y/o modificarlos.

El problema es que tal y como esta hecho ahora es bastante arcaico y feo, y mi idea es implementar un servidor modbus ethernet, o algun tipo de pagina que entres desde el browser y modifiques y leas, el problema es que voy ha hacer esto por primera vez y voy a ir colgando aquí mis avances y ver si alguien me puede ir guiando o corrigiendo.

Del hardware me olvido por que ya esta comprobado que funciona correctamente, por lo tanto voy a ir incluyendo las librerías en un proyecto nuevo, de momento con datos ficticios que voy a guardar en un vector que simulara la tabla de registros de modbus.

¿La primera duda que me encuentro es, que librería seria la mas adecuada para mi?
tenemos:

DHCP client
DNS client
FTP client
FTP server
SNMP agent / trap (SNMPv1)
SNTP client
TFTP client
HTTP Server

Supongo que lo mejor para un Modbus es el DHCP y para que aparezca en el browser un HTTP?

un saludo y gracias.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7851
Re:W5500 servidor por ethernet
« Respuesta #1 en: 23 de Junio de 2020, 09:16:33 »
Necesitas:

DHCP si queres que el IP sea dinamico, dado por el router a donde estes conectado.
DNS si queres comunicarte con www.google.com en ves de usar su IP. Necesitas algo que resuelva el DNS antes de enviar la info.
HTTP Server. El servidor para mostrar las paginas.
SNMP - No lo vas a necesitar
SNTP - Util si deseas tomar el tiempo desde internet, algun servidor NTP.
FTP/TFTP - No vas a subir/descargar archivos asi que seguramente no.
ICMP - Para tenr un ping :3 y probar

Y luego aparte tenes lo de MODBUS. O es via ethernet tambien?

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #2 en: 23 de Junio de 2020, 13:42:32 »
Hola gracias por contestar,

Pues por lo que comentas no creo que necesite DNS, ni FTP/TFTP ni SNTP.

Lo que me gustaría hacer, (no se si estoy diciendo una tonteria) es lo mismo que se hace con el modbus con un rs485 pero por ethernet, en una red local. Entiendo que se puede hacer por que en la norma modbus viene implementado los mensajes para esto:

http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf


En vez de usar el modelo de mensaje PDU seria el ADU. Siendo modbus cualquier cliente podría conectarse. Si esto no es viable, pues entonces me gustaría que desde el browser o buscador escribiera la direccion ip de este, o la MAC o lo que sea y me saliera por pantalla los valores, pero creo que desde el navegador no podria escribir valores por lo que estoy leyendo, todavia estoy muy verde.

Ya he añadido las librerias, ahora estoy modificandolas para comunicarme mediante el spi con el W5500, por cierto estoy usando un Renesas synergy S3A1, aunque no creo que esto influya mucho.

un saludo
un saludo.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7851
Re:W5500 servidor por ethernet
« Respuesta #3 en: 23 de Junio de 2020, 15:23:48 »
Si es unicamente MODBUS, entonces el MODBUS TCP/IP se basa sobre TCP, teniendo el stack TCP/IP + la capa de modbus (que usaria las funciones TCP/IP) entonces tendrias tu codigo, lo que si vas a tener que buscar si encontrar el codigo de esa capa MODBUS.

Si implementas el server HTTP entonces vas a tener si o si la capa TCP/IP, asi que te faltaria solo encontrar eso.. la capa de modbus y hacer la interconexion. Ese ADU vos lo envias a la capa TCP.

Se podria considerar que es el problema mas grande: buscar esa capa que hace de servidor/cliente MODBUS
Microchip ofrece una version basica

https://www.microchip.com/forums/m1053072.aspx

Como para que te guies
« Última modificación: 23 de Junio de 2020, 15:31:13 por KILLERJC »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #4 en: 25 de Junio de 2020, 06:35:19 »
 
Si es unicamente MODBUS, entonces el MODBUS TCP/IP se basa sobre TCP, teniendo el stack TCP/IP + la capa de modbus (que usaria las funciones TCP/IP) entonces tendrias tu codigo, lo que si vas a tener que buscar si encontrar el codigo de esa capa MODBUS.

Si implementas el server HTTP entonces vas a tener si o si la capa TCP/IP, asi que te faltaria solo encontrar eso.. la capa de modbus y hacer la interconexion. Ese ADU vos lo envias a la capa TCP.

Se podria considerar que es el problema mas grande: buscar esa capa que hace de servidor/cliente MODBUS
Microchip ofrece una version basica

https://www.microchip.com/forums/m1053072.aspx

Como para que te guies

Hola, ok de momento ya he conseguido configurarlo todo, con la MAC(un integrado de microchip que me da una mac unica) la ip dinamica, mascara de red etc, esto va bien por que con la aplicación fing del movil veo que esta conectado a la red. Aparece como atmel debido al chip para la mac.

ahora me llegan un poco las dudas sobre como trabaja esta comunicación, es decir, por ejemplo para hacer el modbus en RS485, lo hice yo mismo, cogi el documento este:
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf

y me hice yo las librerias, con sus mensajes de excepción, sus códigos de función el mapeo etc. Pero no se como hacerlo con ethernet.

El siguiente paso que veo es que debo conectarme a un puerto, por lo general el 5000, ¿pero como actuaria un cliente modbus, como le haría la peticion a mi esclavo? que es el MBAP de la trama de 7 bytes para el ethernet.

un saludo.

 

* Sin título.jpg
(20.9 kB, 577x220 - visto 85 veces)
« Última modificación: 25 de Junio de 2020, 06:56:10 por juaperser1 »
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2271
Re:W5500 servidor por ethernet
« Respuesta #5 en: 25 de Junio de 2020, 07:19:29 »
Tienes el grupo de librerías completo en el GitHub de Wiznet: Wiznet ioLibrary

Busca en la raíz de Wiznet que creo que hay también algo para ModBus.

un saludo

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #6 en: 25 de Junio de 2020, 07:23:11 »
Ok he avanzado un poco mas, y ya he conseguido mandar datos y establecer la conexión a un par remoto:

usando hercules (no se si hay una herramienta mejora para esto que estoy haciendo)

 

* Sin título.jpg
(83.22 kB, 653x570 - visto 87 veces)


El código todavia esta muy verde pero básicamente lo que he hecho es (es una maquina de estados asi que lo voy a copiar los trozos que van de manera secuencial para que se entienda sin tener que ir buscando en los estados)

Código: [Seleccionar]
         
{
      //Dirección MAC
                netInfo.mac[0] = AppDatos.Memoria.DireccionMac.Valor[0];
                netInfo.mac[1] = AppDatos.Memoria.DireccionMac.Valor[1];
                netInfo.mac[2] = AppDatos.Memoria.DireccionMac.Valor[2];
                netInfo.mac[3] = AppDatos.Memoria.DireccionMac.Valor[3];
                netInfo.mac[4] = AppDatos.Memoria.DireccionMac.Valor[4];
                netInfo.mac[5] = AppDatos.Memoria.DireccionMac.Valor[5];

                //Dirección IP
                netInfo.ip[0] = 192;
                netInfo.ip[1] = 168;
                netInfo.ip[2] = 0;
                netInfo.ip[3] = 214;

                //Mascara de Subnet
                netInfo.sn[0] = 255;
                netInfo.sn[1] = 255;
                netInfo.sn[2] = 255;
                netInfo.sn[3] = 0;

                //Dirección gateway
                netInfo.gw[0] = 192;
                netInfo.gw[1] = 168;
                netInfo.gw[2] = 0;
                netInfo.gw[3] = 1;

                netInfo.dns[0] = 0;
                netInfo.dns[1] = 0;
                netInfo.dns[2] = 0;
                netInfo.dns[3] = 0;

                netInfo.dhcp = NETINFO_DHCP;

                Inicializacion_W5500();
}

void Inicializacion_W5500(void)
{
    uint8_t temp;
    uint8_t W5500FifoSize[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2, }, {2, 2, 2, 2, 2, 2, 2, 2}};

    reg_wizchip_cs_cbfunc(cs_sel, cs_desel);                        //Indicamos las funciones CS utilizar por el W5500
    reg_wizchip_spi_cbfunc(SPI_Recibir, SPI_Escribir);              //Indicamos las funciones SPI utilizar por el W5500

    if (AppDatos.Memoria.TipoIP == IP_AUTOMATICA)
    {
        if (ctlwizchip(CW_INIT_WIZCHIP, (void*)W5500FifoSize) == -1)
        {
            while(1);
        }

        do
        {
          if (ctlwizchip(CW_GET_PHYLINK, (void*)&temp) == -1)
          {

          }
        } while (temp == PHY_LINK_OFF);
    }

    if (AppDatos.Memoria.TipoIP == IP_AUTOMATICA)
    {
        setSHAR(netInfo.mac);
        DHCP_init(0, DHCP_Buffer);
        reg_dhcp_cbfunc(AsignarIP, AsignarIP, ConflictoIP);
    }
}

después en el bucle principal:

Código: [Seleccionar]
        case ETHERNET_ESTADO_IP_AUTOMATICA:
        {
            uint8_t SocketEstado = 0;
            Cliente_DHCP();

            if(FlagEjecucionTareasEthernet)
            {
                FlagEjecucionTareasEthernet = false;

                wizchip_setnetinfo(&netInfo);                       //Tomamos la informaci
                wizchip_getnetinfo(&netInfo);

                if(socket(0, Sn_MR_TCP, 5000, 0) == 0)              //numero de socket, protocolo, puerto,
                {
                    if(listen(0) == SOCK_OK)
                    {
                        // While socket is in LISTEN mode we wait for a remote connection
                        while((SocketEstado = getSn_SR(0)) == SOCK_LISTEN)
                        {
                                //Colocar algo para salir en caso de que no se establezca la conexión
                        }

                        //Conexión establecida con par remoto
                        if((SocketEstado = getSn_SR(0)) == SOCK_ESTABLISHED)
                        {
                            uint8_t Mensaje[] = "Hola Mundo";
                            uint16_t Longitud = (uint16_t)strlen(Mensaje);
                            send(0, Mensaje, Longitud);
                        }
                        //Algo ha salido mal con la conexión remota. Desconexión
                        else if((SocketEstado = getSn_SR(0)) ==  SOCK_SYNRECV)
                        {
                            ErrorNoAbrePuerto++;
                        }
                        else
                        {
                            ErrorNoAbrePuerto++;
                        }
                    }
                    else                                            //El socket no esta en modo escucha algo salio mal
                    {
                        ErrorNoAbrePuerto++;
                    }
                }
                else //No se ha podido abrir
                {
                    ErrorNoAbrePuerto++;
                }
            }
        }
            break;

/**Ejecuta el cliente DHCP en el bucle principal*/
void Cliente_DHCP(void)
{
    uint8_t ValorDHCP = DHCP_run();

    switch (ValorDHCP)
    {
        case DHCP_IP_ASSIGN:
        {
//            Error = 1;
        }
            break;
        case DHCP_IP_CHANGED:
        {
//            Error = 2;
        }
            break;
        case DHCP_IP_LEASED:
        {
            AppDatos.Memoria.DireccionIP.Valor[0]=netInfo.ip[0];
            AppDatos.Memoria.DireccionIP.Valor[1]=netInfo.ip[1];
            AppDatos.Memoria.DireccionIP.Valor[2]=netInfo.ip[2];
            AppDatos.Memoria.DireccionIP.Valor[3]=netInfo.ip[3];

            FlagEjecucionTareasEthernet = true;
        }
            break;
        case DHCP_FAILED:
        {
//            Error = 2;
        }
            break;
        default:
            break;
    }
}

Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #7 en: 25 de Junio de 2020, 07:25:31 »
Tienes el grupo de librerías completo en el GitHub de Wiznet: Wiznet ioLibrary

Busca en la raíz de Wiznet que creo que hay también algo para ModBus.

un saludo

Hola xocas gracias por responder, he buscado, pero en principio creo que no hay nada para modbus, hay dos aplicaciones que son loopback y multicast, y luego los protocolos para el ethernet son:

DHCP client
DNS client
FTP client
FTP server
SNMP agent / trap (SNMPv1)
SNTP client
TFTP client
HTTP Server

o no he sabido verlo, que también puede ser.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2271
Re:W5500 servidor por ethernet
« Respuesta #8 en: 25 de Junio de 2020, 07:58:07 »
Tienes razón, lo que hay es para algunos de sus módulos.

Para el W5500 encontré esto: WIZ550S2E-Modbus y en la wiki tienes documentación y ejemplos de otros módulos W5500-S2E: https://wizwiki.net/wiki/doku.php/products:w5500s2e-s1:start

Espero que te sirvan de algo...

un saludo

Edito: Para Arduino: https://github.com/goddland16/Modbus-TCP

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #9 en: 25 de Junio de 2020, 08:14:18 »
Tienes razón, lo que hay es para algunos de sus módulos.

Para el W5500 encontré esto: WIZ550S2E-Modbus y en la wiki tienes documentación y ejemplos de otros módulos W5500-S2E: https://wizwiki.net/wiki/doku.php/products:w5500s2e-s1:start

Espero que te sirvan de algo...

un saludo

Edito: Para Arduino: https://github.com/goddland16/Modbus-TCP

Gracias voy a ver que pueedo sacar en claro
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #10 en: 25 de Junio de 2020, 08:51:38 »
Ok por lo que veo, una vez que puedo recibir y mandar datos es bastante parecido a un modbus serie normal y corriente (por favor corregirme si me equivoco)

solo que la trama en vez de ser Direccion-funcion-datos-checksum, es:

MBPA-Funcion-datos siendo MBPA:

-Transación ID (2Bytes): es un numero que da el cliente, por lo que yo como servidor solo tengo que replicarlo en la respuesta.
-Protocolo ID (2Bytes): Para el protocolo modbus siempre es el 0.
-Longitud (2Bytes): Numero de bytes a partir de ahora.
-unitID 1Bytes: igual, lo pone el cliente y el servidor lo repite.

después la trama es igual, pero sin CRC.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2271
Re:W5500 servidor por ethernet
« Respuesta #11 en: 26 de Junio de 2020, 05:57:49 »
Encontré un par de tutoriales sobre el tema que creo te pueden interesar. Modbus TCP/RTU Client/Master y Webserver. Tienen enlace de descarga del proyecto completo (código, librerías, etc).

Creo que abarcan lo que tratas de hacer y te pueden dar pistas de como llevarlo a cabo. Si tienes problemas con el idioma pregunta, porque ahí sí te puedo ayudar.

saludo

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #12 en: 26 de Junio de 2020, 09:13:44 »
Muchas gracias xocas, tirare de google translate y de los subtítulos generados automáticamente y con eso y viendo el código supongo que me aclararé.

De todas formas tengo una duda viendo el documento este: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf

es con respecto a las excepciones, por ejemplo si vemos el diagrama de flujo de la función 0x03, dice que si el número de registros no esta entre 1 y 125 debe dar la excepción 3, pero que pasa si yo solo tengo 20 registros? debo comprobar que este entre 1 y 125 o entre 1 y 20 para dar la excepción 3.

Por que luego también esta la excepción 2, que comprueba que estés en un rango correcto de memoria de registros, entonces en caso de que me pidan leer 25 registros, ¿debo dar la excepción 2 o la 3?

un saludo.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7851
Re:W5500 servidor por ethernet
« Respuesta #13 en: 26 de Junio de 2020, 10:25:41 »
El documento dice claramente

Si se pide inicialmente un registro correcto, pero el largo no... Por ejemplo si se da inicio en el registro 17 y largo 3, esto es bueno ya que ocuparia 17,18,19. Pero si por ejemplo fuera 18 y 3 de largo, trataria de escribir 18,19 y 20, el cual el 20 no es valido, asi que excepcion 2. Esto es tambien para el caso de que supere directamente el valor de 19.

Cantidad de registros  <= (Inicio de direccion+Largo-1)

Ahora la excepcion 3, no es de direccion de memoria, sino de datos fuera de rango.

La figura 9 te da un buen aproximado del manejo de excepciones
« Última modificación: 26 de Junio de 2020, 10:32:45 por KILLERJC »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2802
Re:W5500 servidor por ethernet
« Respuesta #14 en: 27 de Junio de 2020, 08:16:40 »
Bueno pues esto va de lujo, aun no he terminado pero la cosa pinta muy bien.

Esto es un ejemplo de función 3 modbus (lectura de registros de retención) el cual lee 3 registros desde la dirección 0x01A0, desde un cliente modbus tcp IP. Responde correctamente, desde el puerto 502 que es el que se suele usar para modbus.

ya tengo implementada las funciones 3 y 4 y también voy a implementar las 0x06 y 0x10, también estan implementadas todas las funciones de excepción y su respuesta.

 

* Sin título.jpg
(162.3 kB, 804x525 - visto 54 veces)
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw


 

anything