Arduino Forum

International => Español => Software => Topic started by: Kane12 on Jun 14, 2018, 12:12 am

Title: Velocidad de transmisión del Arduino Ethernet Shield
Post by: Kane12 on Jun 14, 2018, 12:12 am
Buenas!

Estoy desarrollando un proyecto en el cual el Arduino funciona como servidor. Utilizo el módulo Ethernet Shield con el chip Wiznet W5100 para transmitir los ficheros almacenados en la tarjeta micro SD a los clientes que se conectan al servidor. Las librerías que uso son la Ethernet.h, la SD.h y la SPI.h.

Mi modus operandi es el siguiente: cada vez que tengo que transmitir un archivo lo que hago es ir llenando un buffer de 1 KB con los datos del archivo y cuando este está lleno se lo paso al cliente. Hago esto hasta que se ha transmitido todo el archivo. El problema es que tengo un archivo que pesa 400 KB y tarda unos 30 segundos en transmitirse (además, en un futuro tendré que enviar archivos que pesaran varios MB y a saber cuanto tardaran en transmitirse).

Mi duda: ¿hay alguna manera de incrementar la velocidad de transmisión? ¿quién me la está limitando? ¿la comunicación por el bus SPI entre Arduino y tarjeta SD/chip Wiznet W5100 o la propia comunicación entre el módulo Ethernet y el router/PC?

Muchas gracias!
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: Lucario448 on Jun 14, 2018, 04:06 am
¿hay alguna manera de incrementar la velocidad de transmisión?



¿quién me la está limitando? ¿la comunicación por el bus SPI entre Arduino y tarjeta SD/chip Wiznet W5100 o la propia comunicación entre el módulo Ethernet y el router/PC?
Yo diría más lo primero. Los factores que lo limitan son los siguientes:




La red en no sería un problema, lo más probable es que las interfaces sean Fast Ethernet, que va hasta los 100 Mbps (12 MB/s). Si hay comunicación inalámbrica de por medio (Wi-Fi), la velocidad sería más como de 54 Mbps (6.8 MB/s).

En cualquier caso, la limitante sigue siendo el Arduino. En Arduino Uno estimo que la velocidad efectiva de transferencia es de más o menos 240 Kbps (30 KB/s) para descarga; y 176 Kbps (22 KB/s) para carga.
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: ard_newbie on Jun 14, 2018, 05:33 am

Esta podría ser la solución:

https://www.emartee.com/product/42271/Taijiuino%20Due%20Pro%20R3%20%20Arduino%20Due%20Compatible (https://www.emartee.com/product/42271/Taijiuino%20Due%20Pro%20R3%20%20Arduino%20Due%20Compatible)
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: Kane12 on Jun 14, 2018, 12:25 pm
Gracias por contestar!

En mi caso no lo había dicho, utilizo un Arduino Mega 2560.

@Lucario448 Buena explicación! Lo único a lo que no veo sentido es a esto:

Quote
Frecuencia del reloj: la mayoría de dispositivos SPI pueden trabajar hasta 20 MHz; pero debido a los 16 MHz de los AVR, la frecuencia máxima del SPI es de apenas 2 MHz (10 veces más lento que su máximo).
¿Por qué la frecuecia del SPI no es de 16 MHz? No entiendo porque tiene que ser de 2 MHz cuando los dos pueden trabajar a 16 MHz.

En cuanto a la configuración de la librería SPI, ¿sabéis si puedo opmitizar algo? ¿o ella lo configura en función del microcontrolador detectado?

@ard_newbie Sería una buena opción! Micro de 32 bits, DMA, CPU Clock a 84 Mhz y 96 KB de SRAM.
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: ard_newbie on Jun 14, 2018, 05:55 pm
@ard_newbie Sería una buena opción! Micro de 32 bits, DMA, CPU Clock a 84 Mhz y 96 KB de SRAM.
Para ver:

https://github.com/elechouse/EMAC-DEMO (https://github.com/elechouse/EMAC-DEMO)

http://forum.arduino.cc/index.php/topic,142908.0.html (http://forum.arduino.cc/index.php/topic,142908.0.html)

tenga en cuenta también, la biblioteca TurboSpi(42 MHz):

https://github.com/anydream/TurboSPI (https://github.com/anydream/TurboSPI)
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: Lucario448 on Jun 14, 2018, 08:14 pm
¿Por qué la frecuecia del SPI no es de 16 MHz? No entiendo porque tiene que ser de 2 MHz cuando los dos pueden trabajar a 16 MHz.
Excelente pregunta. Hay dos motivos por los cuales el reloj general (16 MHz en la mayoría de micros AVR) no es usado como señal de reloj para SPI (SCK):

Así esta configurado por hardware. El controlador SPI en realidad sí parte de la señal general de reloj (la generada por el oscilador externo); excepto que de por medio tiene algo llamado "prescaler", un contador interno utilizado para dividir la frecuencia (con un divisor de potencia 2), retrasando en la salida, el tiempo transcurrido entre conmutaciones.
El controlador SPI de un microcontrolador AVR (también presente en el Arduino Mega) tiene un prescaler cuya división mínima es de 2. Así es, me había equivocado en esa parte; por lo tanto, la frecuencia máxima sería de 8 MHz (de hecho, hasta dentro de la librería SD es lo que se define como "full speed" o "velocidad máxima"); otorgando así una velocidad "bruta" de 125 KB/s. Quizá pienses que sea un mal diseño, pero lo que no sabes es que es se debe a la compensación de la capacitancia e inductancia parásitas (ambos distorsionan una señal digital), y al siguiente motivo.

Carece de DMA. Recuerda que sin este, el CPU debe atender el evento de recepción que ocurre por cada byte (8 bits). Si la señal del reloj general estuviera conectada al del SPI, el CPU estaría "distrayéndose" (más exactamente "siendo interrumpido") cada 8 ciclos. Por si me lo preguntaras, esa frecuencia es tan excesiva que casi no tendría tiempo para ejecutar el resto del programa.
Aunque bueno, no es gran pérdida si se usa SPI.transfer(), ya que esta función es bloqueante de todos modos; pero si el uso del controlador SPI se hiciera "manualmente", sí podría ser un problema.





A 16 MHz, había mencionado que SPI tiene una velocidad de 125 KB/s; sin embargo había dicho que era un valor bruto ya que en la práctica, con tanto código adicional (sobrecargo), un valor más realista sería 100 KB/s o incluso menos. Por lo tanto pondría más o menos 95 KB/s como "máximo absoluto". Con el código de la librería que maneja el dispositivo más los posibles tiempos de espera que entorpezcan una transmisión continua, la velocidad efectiva se reduce aún más (usualmente a 70 KB/s en el mejor de los casos).
Con DMA, aparte de poderse transferir múltiples bytes sin intervención del CPU; en grandes bloques la velocidad efectiva podría acercarse mucho más a los 125 KB/s (de nuevo, a menos que el "esclavo" SPI introduzca retrasos intencionalmente).




En fin, una prueba de por qué el mismo Arduino es el cuello de botella de tu proyecto; aunque se cambie a un micro más veloz y todo, se llegará al punto en que el cuello de botella termina siendo el mismo módulo Ethernet y/o SD. Si se alcanzara dicho punto, no habría más remedio que reemplazar por un SBC o un PC.
Title: Re: Velocidad de transmisión del Arduino Ethernet Shield
Post by: Kane12 on Jun 15, 2018, 11:20 am
Excelente explicación @Lucario448. Muchas gracias!