17 votos

Lectura de un gran número de sensores analógicos en tiempo real

Estoy tratando de construir un controlador de tipo MIDI que tiene un cuello como una guitarra. En ese mástil, hay una enorme matriz de sensores de presión. El controlador emulará 3 cuerdas.

El funcionamiento es el siguiente: Hay 3 tiras largas de cinta de cobre de doble cara (0,5 cm de ancho, tan largas como el cuello) que están conectadas a la alimentación (3,3V o 5V probablemente, no importa por ahora). Sobre estas cintas hay una capa de Velostat, que cambia la resistividad en función de la presión. Encima del velostato habrá otra capa de filas o celdas de cinta de cobre, conectada a algo, que escupe una lectura del voltaje a través de la capa de velostato. Como el cuello tiene unos 40 cm de largo, habrá al menos 80 filas.

Si te imaginas las 3 tiras inferiores de la cinta de cobre como columnas de un gráfico a lo largo del cuello, los sensores serán las celdas o las filas, dependiendo del método de medición (pensé que uno podría ser capaz de multiplexar las columnas también, entonces podría haber filas). Sin embargo, hay algunas condiciones especiales que podrían hacer esto más fácil: Como se trata de un controlador tipo guitarra, no es necesario medir todas las interacciones. Sólo importa el toque más cercano al cuerpo del controlador. Además, una resolución de 8 bits debería ser lo suficientemente precisa. 255 niveles de presión son probablemente más de lo que se necesita de todos modos.

Ahora las partes difíciles:

La medición debe ser lo suficientemente en tiempo real como para detectar martillazos, etc. (no tengo ni idea de la frecuencia de muestreo que debe ser - estimada en varios kHz para una buena medida y jugabilidad) y la salida digital del controlador debe ser MIDI (en 3 canales separados - uno por cuerda) o una señal digital que puede ser procesada con una Raspberry Pi.

Ahora bien, como mis conocimientos son realmente limitados, no pude pensar en las herramientas adecuadas para el trabajo. Lo que sí sé es que: Es posible. Hay un controlador similar pero diferente que utiliza una técnica muy parecida (que prácticamente hice ingeniería inversa hasta que me di cuenta, que tienen una patente y la información sobre cómo lo hacen no es tan arcana como pensaba), se llama ROLI Seaboard.

TL;DR:

  • aproximadamente 240 sensores

  • pueden separarse en grupos de 80 que son alimentados por la misma línea

  • esta es una aplicación en tiempo real, necesito adquirir la presión de cada sensor a medida que se toca (se aplican algunas condiciones, ver arriba)

Gracias de antemano, sé que es mucho para leer. Agradezco cualquier sugerencia y me alegraría mucho que me ayudarais a realizar el terrible lío que me he propuesto.

Cosas que he pensado hasta ahora:

Multiplexando filas y columnas, leyendo cada celda con un MCP3008 o un ADC más grande y encadenando (en cadena o en forma de árbol) ATmegas que sólo empujan la interacción más baja en cuanto a posición a la señal final, pero según mis cálculos, eso podría ser un cuello de botella por la sobrecarga de comunicación. También un modelo anterior incluía potenciómetros de cinta, que he desechado, porque el diseño era malo (varios intentos, no era lo suficientemente genial).

EDITAR/ACTUALIZAR:

¡Gracias por las buenas sugerencias hasta ahora! Gracias a ellas, ahora soy capaz de expresar mi problema con mucha más claridad:

Tengo una matriz de 80 filas * 3 columnas de sensores de presión. Cuando un humano está interactuando con la matriz de sensores, varios sensores en proximidad recogerán el toque, pero sólo a lo largo de una columna. Las columnas están separadas mecánicamente. Los sensores tienen una resistencia entre 100 Ohm y 1 kOhm. Todos estos sensores deben ser leídos con una profundidad de 8 bits, procesados y los resultados deben ser enviados con una velocidad de al menos 1 kHz. Por lo tanto, una sola lectura/procesamiento tiene que tardar menos de un milisegundo. La salida final por columna tiene que ser 4 bytes para un float32 y 1 byte para un uint8. El float32 indicará la posición media de la primera interacción a lo largo de la columna. Una interacción se define como un grupo consecutivo de sensores con una presión superior a un determinado umbral. Aquí es donde entra en juego el procesamiento: la columna se recorrerá hacia abajo hasta que una lectura supere un umbral. Esto contará como el inicio de una interacción. La presión y la posición de cada sensor se memoriza hasta el primer sensor, que cae por debajo del umbral con un máximo de (probablemente) 4 sensores consecutivos. De todos los sensores de la interacción registrada, sólo se procesarán dos sensores: el que lea la presión más alta (resistencia más baja) y el que esté directamente por encima o por debajo de ella. La posición en punto flotante se calcula promediando las dos posiciones de los sensores ponderadas por sus presiones. La presión global de la interacción será sólo la suma de ambas presiones sujetas entre 0 y 255 (sumar ambas presiones de la unidad8 en un uint16 y dividir por 2 sin redondear, descartar los bits innecesarios - esto debería ser rápido). Esto tiene que ocurrir para cada columna. El resultado del tamaño de 15 bytes se enviará entonces a través de SPI a un pequeño ordenador (Raspberry Pi B3) que actúa como sintetizador. No tengo claro el método de transmisión. Si SPI no es la herramienta adecuada para el trabajo, estoy dispuesto a tomar cualquier método de comunicación que un Raspberry Pi puede manejar. Dado que se trata de una aplicación musical-interactiva, la latencia es crucial.

Mis preguntas exactas son: ¿Se puede resolver esto con un solo microcontrolador sin romper el banco? No puedo permitirme comprar varios cientos de dólares en circuitos integrados para un proyecto de aficionado. ¿Qué hardware recomendarías? ¿Existen advertencias no obvias de las que deba cuidarme?

El enfoque que derivé de las respuestas hasta ahora fue alimentar cada columna individualmente, y luego leer las filas con 5 ADCs de 16 canales (ADS7961) conectados a un Arduino sobre SPI. Me preocupa que esto no sea el enfoque más fácil/barato o que no sea lo suficientemente rápido para alcanzar una tasa de >1 kHz.

Descargo de responsabilidad: normalmente soy un químico teórico y un terrible aficionado en lo que se refiere a la ingeniería eléctrica, todo lo que sé es autodidacta y sin ninguna formación profesional (que es a su vez la razón por la que estoy buscando ayuda de personas más conocedoras). Sin embargo, sé cómo funciona el software. Todo lo que tenga que ver con el software, lo resolveré con el tiempo suficiente. Además, soy alemán, así que disculpen los fallos gramaticales ocasionales.

11voto

chharvey Puntos 121

La respuesta obvia es el muxing, esto significa que haces los caminos eléctricos dinámicamente. Así que simplemente iterar a través de toda la matriz, uno a la vez, o como muchos ADC (Analog to Digital Converter) entradas como usted tiene.

Si tienes 3 ADC's entonces puedes leer una fila a la vez, luego cambias las entradas a un mux y voilla, ahora estás leyendo la segunda fila, y luego continúas. El problema con esta configuración es que tienes 80 filas, y no hay ningún mux 80:1 (ochenta entradas a una entrada) que yo conozca. Pero hay 16:1 muxes que puedes juntar para obtener 16*5=80 entradas.

Sería algo así:

row  0-15 [16:1 mux]____________ 5 inputs in [8:1 mux]-ADC
row 16-31 [16:1 mux]_| | | |
row 32-47 [16:1 mux]___| | |
row 48-63 [16:1 mux]_____| |
row 64-79 [16:1 mux]_______|

Las 4 señales de entrada a los muxes 16:1 pueden conectarse juntas.

Así que al final tienes un byte con señales de control en este patrón:

Grouped up:
0, 3 bits for the 8:1 mux, 4 bits for the 16:1 mux

Bit for bit:
0,8:1 MSB, 8:1 LSB+1, 8:1 LSB, 16:1 MSB, 16:1 LSB+3, 16:1 LSB+2, 16:1 LSB+1, 16:1 LSB

Esto significa que necesitará 5 muxes de 16:1 y un mux de 8:1 = 6 CI,

Multiplícalo por 3 porque es posible que quieras leer una fila a la vez.

Esto significa que tendrás 18 IC's, 7 señales de control. Puedes reducir el número de CI si aumentas el número de entradas analógicas. Son 18 con sólo 3 entradas analógicas.

Si en lugar de ello utilizas 240/16 = 15 CI, entonces tienes 15 salidas analógicas de los 15 × 16:1 muxes. Entonces podrías ponerlo en cascada con un mux 16:1, o 16:8 mux. Al final serían 16 IC's si lo "optimizas" con muxes 16:1. Pero esto significaría que tu solución de software no sería tan... elegante como la anterior, sería cruzada y modulada y otras cosas, pero oye, te ahorras 2 IC's.

Así que leerás una fila, la procesarás, luego irás a la siguiente fila, la procesarás, luego la siguiente y etc. Si le das a cada fila 10 µs, entonces harás 80 filas en 0,8 ms, es decir \$\frac{1}{0.8ms}=1.25 kHz\$ que está en el rango en el que estabas pensando.

Es posible, pero es no un buen diseño.

Resolvamos esto de otra manera... más eficiente en cuanto a espacio y dinero.

*20 minutos más tarde* Hmmm... todas las soluciones que se me ocurren son también difícil de configurar y/o requiere una calibración avanzada...

Oh, bueno, entonces asumo que su diseño es apropiado para su tarea.

La mejor de las suertes.


Me pregunto cuáles son esas otras soluciones. ¿Quieres compartirlas? - pandalion98

OP quiere medir la posición y la presión. Son dos parámetros. Esto significa que necesitamos empaquetar esa información dentro de una señal de voltaje para poder leerla y descifrarla. O necesitamos empaquetarla en alguna otra unidad, como ohmios, inductancia, capacitancia.

Aquí están algunas de mis ideas, en las que sólo pienso en una columna. Multiplica la idea por 3 y tendrás la solución completa para una guitarra de 3 columnas.

Primera idea:

Utilice dos cables paralelos (de baja resistencia) que vayan desde la parte inferior de la guitarra hasta el mástil de la misma. Conecte la tierra a uno de los cables en la parte inferior de la guitarra. Haz un sistema de medición LR y mide la inductancia y la resistencia del otro cable, también en la parte inferior.

Al tocar los dos cables con un dedo, se conectarán los dos cables y habrá algunos inductancia aquí. Cuanto más arriba de la guitarra toques, más largo será el circuito y más inductancia medirás. Cuanto más fuerte presiones, más superficie habrá entre los dos cables y menor será su resistencia.

No tienen que ser dos "cables", pueden ser dos cintas conductoras, o cualquier otra cosa.

Por qué no compartí esto antes: Para que esto sea fiable, es necesario calibrar los sensores para cada individuo porque cada uno tiene diferente cantidad de resistencia en su piel. Cada vez que juegues, sudarás y, por tanto, reducirás más la resistencia, así que tendrás que compensar esto. Cada persona suda de forma diferente, por lo que también habrá que calibrarlo por persona.

Así que la inductancia => posicional del dedo. La resistencia => la fuerza con la que se presiona.

La desviación de los valores que medirás estará en el nano y nano H, esto significa que necesitarás unos conocimientos adecuados en cuanto a CMRR y SNR. De lo contrario, todo lo que verás será la tensión de la red, suponiendo que esto se hará en el interior. O algunas otras frecuencias del wifi o las lámparas o algunas otras fuentes de ruido. Así que quizás sea necesario un filtro digital adecuado. Y... probablemente ya está fuera del alcance de las capacidades del OP y del esfuerzo mental aceptable. Así que esta idea queda desechada.

Segunda idea:

Haga una superficie conductora plana en la guitarra que esté conectada a tierra.

Utiliza un cable, o cinta conductora o simplemente un conductor plano. Ponga un poco de pintura no conductora sobre él, o una cinta no conductora normal sobre él.

Póngalo a lo largo de la guitarra desde la parte inferior hasta el cuello de la guitarra. Conecta el cable de la parte inferior de la guitarra a las frecuencias altas, en el rango de cientos de MHz. Ahora empezarás a obtener reflexiones notables. Porque técnicamente tienes una.... mala línea de transmisión donde sólo un lado está blindado.

Así que enviarás algún pulso corto de onda cuadrada y medirás el tiempo que tarda en volver debido a la reflexión por estar tu dedo encima del cable aislado. Y luego mides la amplitud del pico reflejado en la parte inferior de la guitarra. Así que el tiempo de viaje => posicional del dedo. La amplitud del reflejo => la fuerza con la que estabas presionando.

Esto no es lo más fácil de configurar... si no sabes lo que estás haciendo. Así que de nuevo, esto podría ser demasiado esfuerzo para OP para abordar. Así que esta idea es desechada.


Sería algo así:

enter image description here

He supuesto que la impedancia característica es de 150 , es decir, una línea de transmisión muy mala. En realidad podría ser peor, no lo sé nunca he hecho esto.

Aquí está el enlace en el caso de que alguien quiera meterse.

a parte más difícil será hacer coincidir los puntos finales con alguna resistencia, para ello puede que necesites un osciloscopio o algún otro instrumento caro.

La otra parte difícil será medir el TOF (tiempo de vuelo), hay algunos circuitos integrados por ahí, pero no son baratos pero siempre se puede hacer una fuente de corriente constante y llenar un pequeño condensador y luego sólo leer la tensión.

La idea es que cuando un dedo se acerque al cable, su dedo se convertirá en una parte del circuito y actuará como un condensador. Cuanto más cerca esté el dedo, más capacitivo será. Por eso la resistencia en el punto del dedo bajará.

https://en.wikipedia.org/wiki/Transmission_line Desplázate un poco hacia abajo y verás que el parámetro capacitivo forma parte del denominador.

Siempre que un punto del cable esté desajustado, entonces habrá una reflexión, y podrá leerla en la "salida" donde se origina su señal. Si no hay reflexión en ninguna parte, entonces su señal se terminará en cualquiera de los puntos finales.

Cuanto más fuerte empuje hacia abajo, más área de su dedo se aplanará => más capacitancia debido al área. Además, cualquier material no conductor que tengas entre el cable y tu dedo se apretará ligeramente para aumentar aún más la capacitancia.

Tercera idea:

Pegue un theremin dentro de la guitarra y medir la frecuencia y la amplitud. No sé exactamente lo que un theremín dará de sí, pero seguro que algo se puede utilizar.

En este punto se me acaban las ideas y digo que he pasado 20 minutos. Cuando en realidad quizás he pasado 10. Ah, bueno. Ahora seguramente he gastado otros 10 minutos en escribir esto, así que todo suma.

7voto

k.stm Puntos 150

Dependiendo de su rango de precios, puede considerar el uso de una FPGA entre su Raspberry Pi y los ADCs, como el Placa DE0-Nano que tiene un buen soporte como placa de desarrollo FPGA de introducción. Esta solución tiene la ventaja de permitirte escribir un código que sincronice varios/varios ADCs al mismo tiempo y formatee tus datos de una manera que sea presentable para la Raspberry Pi.

Usted mencionó que estaba considerando el MCP3008. Este chip es SPI, por lo que podrías conectar varios dispositivos juntos en el mismo bus con diferentes pines CS. Supón que conectas tres chips a un bus, lo que te da 24 canales ADC por 6 pines (tres líneas de datos y tres líneas CS). Esto significa 240 canales para 60 pines, lo que está fácilmente dentro de las capacidades de la FPGA.

Si se hace funcionar la línea de reloj del MCP3008 a su frecuencia máxima de 2MHz, se necesitarían (15 relojes/canal) * (8 canales/chip) * (3 chips/bus) * (1/2000000 segundos/reloj) = 0,18ms para leer los 240 sensores, lo que corresponde a una frecuencia de muestreo de 5,56kHz.

6voto

Colin Wheeler Puntos 2493

Tres ideas:

1. Hacer un poco de multiplexación en el lado de la oferta

Efectivamente, el circuito que has descrito es un gran número de resistencias variables, cada una con un extremo común a una tensión de alimentación. Quieres leer todos los valores de las resistencias y las otras respuestas hasta ahora han sugerido principalmente enfoques para multiplexar la señal en el lado analógico.

Pero también se podría hacer una parte o la totalidad de esta multiplexación en el suministro lado, dividiendo el "carril" de suministro en n secciones. Conecte los conjuntos de n que tienen cada uno una vía de alimentación diferente. Ahora energiza sólo una vía de alimentación a la vez y utiliza una entrada ADC para leer cada conjunto de almohadillas. (Así es como suele funcionar el circuito que lee el teclado de un ordenador, y la forma en que se cablean los interruptores suele llamarse "interruptor de punto de cruce"). En última instancia, podrías utilizar un único ADC, conectado a todos los 'raíles', y hacer todo el multiplexado conectando la alimentación a cada pad por turnos.

La única pega es que todas las demás almohadillas tienen que estar aisladas del raíl de alimentación, no conectadas a tierra, como sería el caso si sólo se utilizara una salida digital para cada una. Hay varias maneras de resolver esto, incluyendo el cableado de cada almohadilla a través de un diodo, transistor bipolar o FET, o - no sé lo rápido que se puede hacer en la práctica, pero es posible en principio - utilizando el pin de entrada-salida de un microcontrolador y el establecimiento de cualquiera de salida de alta o para ser una entrada, cuando se debe tener una impedancia relativamente alta.

La precisión de la medición de tus sensores mediante esta técnica puede no ser perfecta en comparación con el uso de una única fuente de tensión fija y multiplexores analógicos de alta calidad, pero sospecho que será lo suficientemente buena, especialmente porque estoy seguro de que los sensores de presión tendrán cierta tolerancia en su resistencia - es posible que tengas que calibrar esto para cada sensor utilizando una fuerza de referencia de todos modos.

2. Utilizar algunos microcontroladores con muchas entradas ADC

Por ejemplo, el PICAXE 40X2 tiene 27 pines que se pueden utilizar como entrada analógica, por lo que podrías cubrir tus necesidades con 9 de ellos. Está programado en un lenguaje BASIC simple y puede actuar como un esclavo i2c - por lo que podría leer los 9 chips con un microcontrolador más - o probablemente podría enviar la salida de cada chip como datos en serie y leerlo en el ordenador central a través de convertidores de serie a USB. No puedo prometer exactamente lo rápido que va a ir, pero creo que debería funcionar bien si usted reloj de la PICAXE a la velocidad máxima (de 64 MHz, utilizando un resonador externo de 16 MHz). Por supuesto, si eres feliz con la programación de microcontroladores en C, entonces puedes hacer lo mismo con el PIC18F45K22 en el que se basa el PICAXE.

3. Utilizar unidades de entrada analógica estándar

Por último, si no le importa gastar dinero para ahorrar tiempo, y la portabilidad no es una gran prioridad -por ejemplo, si está bien que el instrumento esté atado a un bastidor de equipos por algunos cables gruesos-, podría simplemente comprar suficientes dispositivos de entrada analógica de alto número de canales para medir todos los sensores a la vez. Por ejemplo, el Medición informática USB-2633 lee 64 entradas analógicas por poco más de 1.000 dólares.

4voto

Spehro Pefhany Puntos 90994

Podría valer la pena considerar un acondicionamiento de señal de fuerza bruta (pasivo quizás) seguido de ADCs pequeños o MCU/ADC con 16 o más entradas de ADC MUX'd cada uno. Son sólo 40 chips. Un ejemplo de un chip que podría funcionar es el ADS7961QDBTRQ1 que tiene un modo de canal de autoincremento y 16 entradas.

La tasa de datos total, incluso con una tasa de muestreo de 4kHz y 240bytes por muestra, es de alrededor de 1MB/s, lo que no es demasiado aterrador. Quizás una CPU maestra con un bus SPI de 10MHz o 20MHz comunicando a los esclavos. Usa 2 buses SPI si el ancho de banda no está ahí. La parte mencionada arriba trabaja a 20MHz así que un solo SPI servirá.

O tal vez pueda utilizar un solo chip de TI: el DDC2256AZZF que tiene 64 canales de muestreo simultáneo y 256 entradas pero no es especialmente barato (unos 350 dólares) y viene en una matriz LFBA de 14x14mm y 323 pines, por lo que no va a funcionar con una protoboard blanca.

3voto

Virtlink Puntos 593

Para una aplicación de interfaz humana en tiempo real, una frecuencia de muestreo global de varios khz parece elevada. 50Hz es probablemente suficiente ( https://en.wikipedia.org/wiki/Input_lag#Typical_overall_response_times ). Esto significa que tienes que muestrear todos los sensores en <20ms, así que 80us por sensor. Esto no es demasiado difícil, y puede ser manejado por básicamente todos los microcontroladores normales de 8 bits (es decir, Atmega88 puede hacerlo en <30us).

También podrías medir todas las interacciones y luego descartar las que no necesitas, ya que medirlas todas no es tecnológicamente difícil. El problema viene de la multiplexación. Estoy un poco confundido en tu post, porque dice que los sensores se alimentan 80 a la vez? Lo normal es, como dices, multiplexar columnas y filas. Si no haces eso, tendrás que lidiar con >80 cables saliendo de tu dispositivo, lo que realmente no es una gran idea. Necesitas encontrar una manera de dividirlo en una matriz, de modo que tengas 30 cables (que sigue siendo mucho). Entonces podrías multiplexarlos, etc., pero si yo fuera tú, simplemente tendría varios microcontroladores y los conectaría a un maestro. Podrías usar un ADC dedicado en lugar de los MCUs esclavos, pero yo personalmente me quedaría con los MCUs.

Has identificado correctamente que las comunicaciones podrían ser un problema, pero esto no es un gran problema, al menos entre las MCU. Un Atmega a 8MHz puede hacer SPI a 2MHz, por lo que el envío de todos los datos del sensor tardará <1ms. La cuestión entonces es qué quieres hacer con estos datos después de que la MCU maestra los tenga.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X