Escribir en un puerto paralelo con una latencia mínima

1

Quiero usar un puerto paralelo para controlar algunos motores paso a paso (muchos de ellos). Hasta ahora lo he conectado a una pequeña placa de prueba con LED y he escrito un programa de C en Linux para establecer los pines utilizando las llamadas outb o outl . Como quiero usar los 12 pines de salida, estoy configurando el byte de datos y el byte de control. (En realidad, más de 12 pines serían agradables, pero 12 tendrán que hacerlo).

Todo esto funciona y los LED se iluminan como se esperaba, pero es un poco lento para mis necesidades. Un bucle con 1,000,000 iteraciones que llaman outb dos veces (byte de datos y control) toma ~ 3.9 segundos. Si sustituyo eso con una sola llamada outl que toma ~ 3.6 segundos, entonces parece que cada outl toma aproximadamente 3.6 nosotros. Por lo que leí debería funcionar en aproximadamente 1 nosotros o incluso menos. La pregunta es: ¿cómo lo hago más rápido?

La máquina es un Sempron de AMD con un puerto paralelo incorporado. Hay 3 configuraciones para el puerto en BIOS: "Bidireccional", "ECP" y "EPP". ECP da los números de arriba. La bidireccional es ligeramente más lenta y el EPP es mucho más lento (ejecutando exactamente el mismo código). ¿Hay algo especial que deba hacer en el código para aprovechar los modos más rápidos? ¿Es una limitación del hardware, por lo que tal vez una tarjeta PCI IO dedicada sería más rápida? ¿Necesito usar DMA (que creo que requiere un controlador en modo kernel)?

Alternativamente, ¿hay algún dispositivo adicional por ahí como un puerto paralelo, pero con más pines y / o menor latencia para configurar todos los pines? (No necesito cambiar un pin a la vez).

Editar (más detalles):

Quiero controlar 1,000 motores paso a paso en total. El diseño original era tener 5 Arduinos controlando 200 motores cada uno usando puertas lógicas para abordar cada motor en secuencia. Un 6º Arduino sería el controlador "maestro", que envía datos a los otros 5. Sin embargo, un Arduino no tiene suficiente memoria para almacenar todos los datos que quiero enviar, de modo que es donde entró una PC. Una vez que una PC estuvo involucrado, parecía mucho más sencillo si pudiera eliminar los Arduinos por completo y usar 2 (quizás 4) puertos paralelos para controlar los motores directamente, probablemente bajo RTLinux (aunque la prueba anterior se realizó en Linux normal). No creo que necesitara una resolución de 1 temporizador como tal. Estaba pensando en un temporizador disparando cada 1500-2000 uS y cada vez enviando señales a los 1000 motores, uno por uno (500 o 250 por puerto paralelo). La velocidad del puerto paralelo parece ser la limitación aquí.

Entiendo que hay controladores de motores paso a paso dedicados, pero comprar 1000 de ellos es caro. ¿Hay algo que pueda controlar muchos de ellos? Lo ideal sería mantener la mayor cantidad de trabajo posible en la PC, porque es mucho más fácil de programar y depurar.

    
pregunta EM0

8 respuestas

3

Para la generación de impulsos simple para 1000 motores paso a paso, lo que desea es un FPGA donde pueda crear muchas copias de un motor de secuenciador simple y conectar cada copia a su propio pin de salida.

Sin embargo, la gran mayoría del costo de un sistema de controlador de motor paso a paso está en los transistores de conmutación de potencia, FET, (o para motores más pequeños, IC) - y los motores mismos, no el pulso de paso generador.

Una vez que esté creando un módulo con la electrónica de conmutación por motor (o por un número pequeño de motores), el costo de colocar un microcontrolador allí que pueda aceptar comandos de alto nivel sobre algún tipo de bus serie direccionable es menor.

Para empezar, todo el proyecto parece bastante inverosímil. Antes de hacer cualquier cosa con 1000 motores, debe adquirir cierta experiencia práctica en sistemas con una media docena más o menos.

    
respondido por el Chris Stratton
3

Eche un vistazo a www.LinuxCNC.org. El propósito de esta distribución de Linux es conducir motores de paso para máquinas CNC de bricolaje. El kernel de Linux fue parcheado para agregar comportamientos limitados en tiempo real. Una forma que utilizan para controlar los motores es ... el puerto paralelo. El kernel tiene rutinas dedicadas en tiempo real que nos ejecutan cada xxx con un menor nerviosismo para impulsar los controladores del motor. El núcleo también integra toda la lógica necesaria en caso de que desee agregar algún tipo de control PID a sus motores. Pero ... no sé qué tan bien se puede escalar si tiene que controlar 1000 motores ...

    
respondido por el Blup1980
2

Este es el tipo de aplicación en la que realmente no quieres estar haciendo el control de bajo nivel de bits individuales al escribir software en una computadora de gama alta. Debe agregar un poco de hardware externo para manejar esos detalles de bajo nivel mientras que el sistema principal se ocupa del comportamiento de alto nivel. La comunicación entre los dos tiene menos restricciones en tiempo real y se puede implementar utilizando USB, puerto serie, Ethernet o buses serie integrados como SPI o I 2 C.

Puede obtener chips dedicados para el controlador de motores paso a paso, o puede programar un microcontrolador de uso general (muchos de los cuales tienen hardware dedicado para impulsar motores y leer codificadores de posición, por ejemplo) para hacer el trabajo.

    
respondido por el Dave Tweed
2

Creo que la respuesta de @ DaveTweed es bastante acertada, pero me gustaría añadir algunas cosas más a esto.

Usted dice que una sola llamada de outb debería tomar 1 uS o menos. ¿Por qué piensas eso? No hay nada (hardware o software) que garantice ese nivel de rendimiento.

Para empezar, ¿se está implementando outb como una macro en línea, o está generando una llamada a función real? Incluso si es una macro en línea, ¿qué más está haciendo esa macro? ¿Podría ser la gestión de varias asignaciones de direcciones lógicas a físicas? Todas estas cosas requerirán tiempo y podrían prolongar el tiempo de ejecución de outb o outl.

Luego están las cosas del hardware que podrían causar esta velocidad. PCIe, por ejemplo, es conocido por hacer que los accesos de un solo byte / palabra sean lentos. Las escrituras suelen ser mucho más rápidas que las lecturas, pero puedo ver cómo las escrituras en el puerto paralelo podrían ir a > 1us cada una. Otros estándares de bus pueden tener diferentes efectos en la velocidad, así como la topología del bus (ubicación y tipo de puentes de bus). No ayuda que los fabricantes de chips de PC y placas madre no estén motivados para hacer que las interfaces de puertos paralelos se ejecuten rápidamente.

Incluso si funcionó rápido en este sistema, no significa que se ejecutará rápidamente en el siguiente sistema. Para empeorar las cosas, Linux no es un sistema operativo en tiempo real. No hay garantía de que obtendrá el rendimiento que desea cada vez. Podría tenerlo funcionando bien por un tiempo y luego Linux hace algo que detiene sus pulsos del motor paso a paso durante 100 ms o más. Existen versiones de Linux en "tiempo real" que mejoran las cosas, pero no mejoran las cosas al nivel de 1 uS.

Si estuviera haciendo esto, obtendría un buen ARM Cortex M0 / M3 / M4 con una interfaz USB y haría que el ARM hiciera todo el control del motor paso a paso. Y luego solo conéctelo a su PC a través de USB. Hazlo bien y ARM podría hacer todo tipo de cosas de control de motores que serían muy difíciles de hacer en Linux.

    
respondido por el user3624
1

** 2da edición * Ahora que ha leído sus detalles agregados, debe considerar un enfoque ascendente y descendente para controlar 1024 motores desde un solo puerto. La parte inferior está arriba ... desea una duplicación mínima de hardware y de arriba a abajo desea aislamiento de fallas y control direccionable para el dispositivo (10 bits), dirección (1 bit) y distancia, velocidad para los bits restantes con detección de errores CRC en E / S. Este tipo de comunicación se desarrolló originalmente utilizando protocolos seriales ADLC y SDLC con chips estándar.

Esta pregunta intenta preguntar "¿Cómo diseñaría un sistema de control para 1000 motores paso a paso, que tal vez cuesta $ 500 para 1000 motores en miniatura? Esto no será fácil, e incluso más difícil con la detección de fallas, el aislamiento. Sin eso, imagine qué tu MTBF va a ser y hora de depuración ??

Leí los simposios que intentaron responder, ¿qué haría con él si tuvieras un sistema así? p.ej. Una flor de animanemona fluida. enlace

** Consultaría a Microchip para obtener una solución de matriz económica. Comience con un diagrama de bloques y una lista de requisitos antes de cualquier diseño. Luego vea qué comunicación se adapta mejor a su aplicación. Un canal sincrónico en serie personalizado puede ser mejor que un canal direccionable al ahorrar en la sobrecarga con el direccionamiento utilizando canales en serie síncronos similares a los controladores en serie LCD que utilizan la interfaz en serie con pantalla (DSI).

  

Es necesario pensar más en los requisitos de nivel superior en lugar de   la interfaz de hardware de bajo nivel en el modelo OSI y definir todas las   Requisitos antes de elegir un confiable, económico, mantenible   diseño. Un enfoque de mapeo de píxeles LCD puede ser todo lo que necesita hasta que   tener un pixel muerto. j / k.

** la última edición terminó *

** Añadido * El puerto paralelo está limitado en velocidad por la configuración del BIOS, su controlador LPT y el búfer externo LPT. La tarjeta enlazada a continuación utiliza un FIFO de 8 bits x 512 para amortiguar la salida y lograr tasas de datos de 2 a 1 uS. Siendo que no es barato ni está diseñado para motores paso a paso. No lo recomiendo

  • Paso pulso y dirección.
  • Paso y paso

    Así es como debes diseñar tu sistema. Microstepping, el control de velocidad de velocidad de giro para una velocidad de búsqueda óptima puede ser mejor (más barato y más precisamente) manejado por hardware discreto, como lo hicieron algunas unidades de disco japonesas ST506, hace 30 años. Aunque la curva de aprendizaje y la experiencia de diseño se requieren en este método. Si lo deseo, puedo buscar ejemplos que sé que existen.

Si reduce los requisitos de velocidad de reloj, estas herramientas pueden ser útiles. enlace

* finalizar edición *

Hay una solución de puerto paralelo 1uS pero la tarjeta cuesta alrededor de $ 500. enlace La tarjeta utiliza un FIFO para amortiguar las transferencias de puerto paralelo.

La solución más rentable es la que tiene una gran demanda de volumen. Su presupuesto y los requisitos de E / S deben definirse mejor para las variaciones de latencia. De lo contrario, vuelva al tablero de dibujo y delegue el ancho de banda del control a una solución de hardware dedicada y utilice la PC para controles de alto nivel.

Normalmente, 100 ~ 150KB / s es la velocidad máxima en el puerto paralelo. Has hecho bien en obtener más sin un FIFO. Pero, ¿qué variación de latencia puedes tolerar?

    
respondido por el Tony EE rocketscientist
0

Eche un vistazo a los tableros del proyecto Armadeus: enlace Proporcionan una pequeña placa basada en ARM de código abierto con un linux incorporado. Algunos de ellos tienen un FPGA conectado a la ARM. También proporcionan ejemplos sobre cómo acceder al FPGA desde el Linux incorporado. Podría ser interesante implementar el control y la interfaz de sus 1000 motores en el FPGA y usar una aplicación de Linux de espacio de usuario para impulsar el FPGA.

    
respondido por el Blup1980
0

Si el único motivo por el que no pudo usar un Arduino fue su memoria limitada, tal vez podría evitarlo agregando algo de memoria externa al Arduino. Sospecho que la forma más sencilla de agregar memoria externa es mediante el protocolo de la tarjeta SD / MMC.

Hay una biblioteca de Arduino que hace que leer (y escribir) tales tarjetas sea bastante simple. Para más detalles, recomiendo el Tutorial sobre tarjetas Micro SD de Lady Ada. También puede encontrar útiles las preguntas etiquetadas o aquí en Electronics Design stackexchange, o una búsqueda en la web para tarjeta SD arduino .

    
respondido por el davidcary
0

Ignorando todos los problemas de idoneidad o las opciones de hardware y software para este propósito, tomaré su pregunta original a su valor nominal. ¿Es posible que la sobrecarga para el bucle sea aproximadamente 3 us? Recodifica tu bucle para ejecutar el 10% de las instrucciones de out seguidas y haz que el bucle funcione 100.000 veces. Ver si el tiempo de ejecución es apreciable. Esto le dirá al menos una cosa sobre la ejecución de esas instrucciones.

    
respondido por el gbarry

Lea otras preguntas en las etiquetas