XMOS startKIT:Creación de un XMOS y un robot Raspberry Pi XMP-1
Introducción
El XMOS startKIT de Farnell (o Newark) es una plataforma de procesador de muy bajo costo (£ 12 incluido el IVA) que funciona bien con la Raspberry Pi. Juntos es posible construir aplicaciones robóticas casi sin necesidad de soldaduras.
El XMOS startKIT es una placa del tamaño de una tarjeta de crédito con un chip XMOS con múltiples 'núcleos XMOS' que se pueden programar en C. La tecnología XMOS permite que las cosas funcionen en paralelo a alta velocidad con baja fluctuación. Estas son exactamente las características que podrían ser ideales para aplicaciones robóticas.
Junto con algo de código para ejecutar en la placa XMOS startKIT y en la Raspberry Pi (RPI), las placas se utilizan para construir una plataforma móvil compacta simple (la voy a llamar XMP, XMOS Mobile Platform en lugar de un robot a partir de ahora en el espíritu XMOS de preceder todo con 'X').
Aunque el XMP-1 no es un gran robot hasta que tenga algunos sensores y más programación, podría extenderse en el futuro para experimentos de robótica. El XMP-1 utiliza hardware estándar de bajo costo y no utiliza herramientas exóticas más allá de un destornillador, cortadores de alambre y alicates.
Esta publicación cubre la comunicación entre la placa RPI y XMOS usando una interfaz de interfaz periférica en serie (SPI) y cómo construir el XMP-1 y controlarlo desde un navegador web.
El video aquí muestra a XMP-1 enseñándole una ruta; el primer intento de usarlo! Se beneficiaría de una mejor interfaz de usuario. XMP-1 puede moverse bastante rápido, pero me lo tomé con calma aquí a baja velocidad. A la derecha está el control del navegador, y en la parte inferior está la salida de la consola, simplemente generando algunos mensajes de estado y de mantenimiento para ver qué está ocurriendo.
El siguiente video a continuación muestra el XMP-1 intentando reproducir la ruta y causando sufrimiento y dolor en el camino. Mis servos de rotación continua de bajo costo (que se utilizan para impulsar las ruedas) no eran muy buenos y el XMP-1 aún no tiene sensores.
Un poco más de detalle
Esta publicación es en realidad la parte 2 de algunos experimentos de XMOS startKIT. La Parte 1 contiene la introducción, la terminología, la arquitectura de XMOS y una guía de inicio rápido con programas de ejemplo. Si está interesado en la tecnología, entonces puede ser útil seguir la parte 1 primero, para que esta parte 2 tenga más sentido. Esta parte 2 está destinada a construir un marco simple para comunicaciones de alta velocidad entre la Raspberry Pi y la placa XMOS startKIT. El marco debe ser lo suficientemente de propósito general para poder usarlo en muchos proyectos (la robótica no era mi intención). El XMP-1 es realmente solo un subproducto, en el deseo de probar las comunicaciones de la placa Raspberry Pi a XMOS. Aquí se registra en caso de que sea útil. (Tenga en cuenta que también hay una parte 3 titulada XMOS startKIT:XMOS y Raspberry Pi Osciloscopio XAE 1000 que reutiliza la capacidad SPI discutida en esta publicación, e introduce cómo usar el convertidor analógico a digital (ADC) que está presente en el chip XMOS y cómo realizar gráficos en tiempo real en un navegador web).
Si solo está interesado en construir y usar XMP-1, simplemente puede tomar el código en la parte inferior de la publicación, compilar y almacenar en Flash (como se describe en la parte 1) en la placa XMOS startKIT y Raspberry Pi, y simplemente siga las secciones que describen el ensamblaje del hardware XMP-1, omitiendo el resto del contenido aquí. Si está interesado en controlar cualquier hardware con Raspberry Pi y un navegador web, puede reutilizar parte del código aquí. Pero, para aprovechar al máximo la combinación de Raspberry Pi y XMOS startKIT, la información restante aquí puede ser útil si es nuevo en el startKIT.
Descripción general de la solución:hardware y software
Aquí hay una foto del XMP-1 completo que se está cargando. Para uso en exteriores, utilicé un dispositivo tipo hotspot 802.11 (MiFi), ejecutando el navegador en un teléfono móvil.
El siguiente diagrama muestra el diseño aproximado de los bits y piezas como se ve desde la parte posterior del XMP-1. Puede ver que es bastante básico:XMP-1 fue solo un experimento rápido.
La Raspberry Pi (RPI) se usa para manejar toda la actividad de la red. Ejecuta un pequeño servidor web y la mayor parte del código está escrito en JavaScript en una plataforma Node.js. El RPI comunica las velocidades de control del motor (en realidad, se utilizaron servos de rotación continua para XMP-1) a través de una interfaz en serie (SPI) a la placa XMOS startKIT. El kit de inicio XMOS es responsable de alimentar señales de modulación de ancho de pulso (PWM) a los motores.
El RPI se conecta a la red mediante un adaptador USB WiFi 802.11.
El diagrama de cableado completo se muestra aquí. El hardware y la construcción se describen más adelante.
El siguiente diagrama muestra el software que se implementará en el RPI y en el startKIT. Parece mucho, pero no lo es y se puede dividir en partes pequeñas que se describirán más adelante. Como se mencionó, el código fuente completo está al final de esta publicación, por lo que podría usarse sin ninguna modificación si lo desea.
En resumen, el bloque verde maneja la interacción web y determina la velocidad y la dirección de los motores según la entrada del usuario. El bloque verde proporciona una página web (index.html) al usuario que incorpora la interfaz de usuario. El programa xmos_servo es un pequeño software escrito en C que traduce la velocidad / dirección deseada en bytes de datos de interfaz periférica en serie que se envían al startKIT. El software startKIT se divide en tres partes que se ejecutan simultáneamente en núcleos XMOS separados. Spi_process convierte las señales SPI en datos que se almacenan en una matriz. El código data_handler inspecciona la matriz para decidir qué hacer (la única conclusión a la que llega hoy es manipular los servos). El proceso servo_handler envía un flujo de pulsos a los servos, para que puedan girar a la velocidad deseada. Todos estos bloques se explican con más detalle a continuación.
Interfaz de periféricos en serie (SPI)
SPI se basa en cuatro cables conocidos como SS, SCLK, MISO y MOSI y una asignación de maestro y esclavo para los dos dispositivos involucrados en la comunicación. En el caso de la placa RPI y XMOS, el RPI es el dispositivo maestro y es responsable de generar la señal de reloj. El RPI transmite datos en el cable MOSI y recibe datos en el cable MISO. Esto significa que la interfaz SPI puede transferir datos de forma bidireccional al mismo tiempo. En la práctica, si se requieren datos unidireccionales, la señal MOSI o MISO se puede ignorar según la dirección de interés.
La captura de pantalla del osciloscopio aquí (señales individuales y la decodificación SPI automatizada de un osciloscopio Tektronix MSO2024B) muestra un ejemplo de comunicación SPI usando la Raspberry Pi. SPI se puede configurar de varias formas; Puede ver en este ejemplo que se transfirieron tres bytes de datos del maestro (RPI) al esclavo (placa XMOS) y que eran 0x02, 0x00 y 0x10, y no se transfirieron datos o 0x00, 0x00, 0x00 desde el esclavo del maestro simultáneamente.
El cable SS es una señal de selección de chip (activo bajo). El RPI tiene dos pines en su conector de 26 vías que podrían usarse para SS; se muestran en un círculo en azul en el diagrama a continuación, marcados CE0 y CE1. Esto significa que el RPI puede hablar con dos dispositivos esclavos SPI si lo desea. En este caso, solo se usó uno de los pines CE:elegí CE1.
ontrol de servomotores de hobby
Los servomotores Hobby generan un movimiento basado en una señal de entrada. Por lo general, giran menos de una revolución completa. Por lo general, un servo de hobby girará dentro de un rango de aproximadamente 180 grados. El eje de salida se puede conectar a (digamos) uniones para hacer que las ruedas giren completamente a la izquierda o a la derecha (o cualquier punto intermedio) según la señal de entrada.
El diagrama a continuación muestra los componentes internos de un servo de pasatiempo típico (tomado de este sitio). A la izquierda (en azul) hay un motor de CC convencional. Está muy orientado hacia abajo, y el eje final se puede ver a la derecha conectado a un brazo azul que podría estar conectado a un mecanismo de dirección de rueda, por ejemplo. Debajo del eje final habrá un potenciómetro, que proporciona información sobre la posición exacta del eje final. Por lo tanto, un servo de hobby es un sistema de circuito cerrado y puede autocorregirse si el brazo se aleja accidentalmente de la posición deseada.
Los servos de hobby suelen tener tres conexiones; 0V, 5V y señal. El cable de señal es una entrada digital al servo y requiere una señal PWM. El tamaño del ancho del pulso determina el ángulo al que se moverá el eje. La señal PWM debe repetirse cada 20 milisegundos, y un ancho de pulso de 1.5 milisegundos hará que el eje se mueva a una posición centrada. Un ancho de 1 mseg moverá el servo completamente en una dirección, y un ancho de 2 mseg moverá el servo completamente en la otra dirección (más abajo habrá algunos rastros del osciloscopio de control del servo).
Existe un tipo de servo modificado conocido como servo de "rotación continua". Es un servo modificado donde se quita el potenciómetro junto con los topes finales, y se persuade al circuito para que piense que el servo todavía está en la posición centrada. El envío de PWM con un ancho de pulso distinto de 1,5 mseg hará que el mecanismo gire en el sentido de las agujas del reloj o en el sentido contrario a las agujas del reloj a una velocidad que depende del ancho del pulso. El XMP-1 utiliza dos servos de hobby de rotación continua, uno para cada rueda. No son una forma óptima de obtener un movimiento controlado (XMP-2 utilizará motores con escobillas de CC) ya que se están utilizando para un propósito diferente al original de los servos de hobby, pero tienen la ventaja de que pueden ser controlados por un dispositivo digital. señal lógica y no requieren ningún circuito de puente H externo.
Los cables de los servos de Hobby se pueden codificar por colores de manera diferente según el fabricante. Por lo general, el cable central es rojo y va a + 5V. El cable negro o marrón es 0V. El cable blanco o amarillo es la entrada de señal PWM.
Inicio del desarrollo:conexión de las placas
Para desarrollar el software, el RPI y el startKIT se conectaron mediante un cable plano y un conjunto de conector IDC; estos se pueden ensamblar con un tornillo de banco o se pueden comprar listos para usar. Para una versión autoensamblada, vale la pena comprar un conector IDC adicional para usarlo como conector de depuración en el centro del cable, para facilitar la vida al sondear señales con un multímetro o un osciloscopio.
Implementación de SPI (spi_process) en el kit de inicio XMOS
El uso del entorno de desarrollo XMOS (xTIMEcomposer) se cubrió en la parte 1. Las capturas de pantalla a continuación muestran la versión para Windows de xTIMEcomposer, pero la versión de Linux parece idéntica (y posiblemente la versión para Mac también puede verse similar).
En este punto, puede hacer clic con el botón derecho en la biblioteca de funciones esclava SPI en el laboratorio de xSOFTip e importar la biblioteca al espacio de trabajo. No soy un experto en xTIMEcomposer, por lo que probablemente lo esté usando mal aquí, pero el código fuente y el archivo de encabezado de la biblioteca aparecieron en una carpeta separada en el Explorador de proyectos (que se muestra en un círculo en azul a continuación):
Se requería que los archivos estuvieran en la carpeta spi-test (para que aparezcan como se muestra en un círculo en verde arriba) para lograr eso copié manualmente los archivos spi_slave.hy spi_slave.xc de la carpeta module_spi_slave / src en la carpeta spi-test / src carpeta usando el Explorador de Windows.
El software utiliza el concepto de puertos para controlar la salida o leer la entrada. Hay un mapeo entre estos puertos lógicos y el mapeo físico hacia el pin en el chip. Las asignaciones se pueden modificar en determinadas combinaciones (consulte la figura 3 en el documento PDF Introducción a los puertos XS1).
Los puertos de entrada / salida de los dispositivos XMOS pueden tener un ancho de 1, 4, 8, 16 o 32 bits. Al diseñar con la pieza, es posible que desee asignar ciertas funciones a puertos de 1 bit u otras funciones a puertos de varios bits, por lo que la figura 3 será muy útil para determinar qué puertos y pines usar.
Con el código esclavo SPI ahora en el filtro spi-test / src, este código se modificó ligeramente. El código de la biblioteca supone que los puertos que se utilizan para la interfaz SPI son todos puertos de 1 bit, mientras que el pin SPI SS de Raspberry Pi (CE1) está conectado a un puerto de 32 bits en la placa XMOS. La Figura 8 del documento PDF del Manual de hardware de startKIT se muestra a continuación. En el centro en verde puede ver el encabezado de 2 × 13 vías que se conecta entre la placa XMOS y la Raspberry Pi. A la izquierda y a la derecha en azul están los nombres de los pines físicos en el chip (X0D0, X0D11, etc.). Los valores de los pines resaltados son los números de puerto lógicos. P1A, P1D, etc. son puertos de un solo bit. P32A1 es el primer dígito binario de un puerto de 32 bits
Se realizaron bastantes cambios en la biblioteca SPI y el código completo se adjunta a la publicación, por lo que solo se describirán algunos fragmentos de código aquí, no es necesario copiar / pegar, el código completo se adjunta al final de esta publicación. se puede utilizar.
La interfaz SPI en el dispositivo XMOS se inicializa como se muestra aquí. Se explica con más detalle a continuación.
+ expandir sourceview simple- void spi_slave_init (spi_slave_interface &spi_if)
- {
- int clk_start;
- set_clock_on (spi_if.blk);
- configure_clock_src (spi_if.blk, spi_if.sclk);
- configure_in_port (spi_if.mosi, spi_if.blk);
- configure_out_port (spi_if.miso, spi_if.blk, 0);
- reloj_inicio (spi_if.blk);
- return;
- }
Como se mencionó en la publicación de la Parte 1, las E / S se pueden registrar dentro y fuera del dispositivo XMOS en momentos precisos. En el código anterior, la función set_clock_on (definida en el archivo de encabezado XMOS xs1.h) se usa para activar uno de los mecanismos de reloj integrados en el chip XMOS. El siguiente diagrama (del documento Introducción a los puertos XS1) muestra este mecanismo en amarillo. La función configure_clock_src se utiliza para seleccionar un reloj externo (mostrado en azul en el diagrama). Se conectará al pin SCLK de la Raspberry Pi. Las funciones configure_in_port y configure_out_port se utilizan para vincular puertos al mecanismo de reloj. Tanto las señales MOSI como MISO (que se muestran en verde a continuación) están configuradas para vincularse al mecanismo de reloj.
La forma en que se manejan los datos en serie en los dispositivos XMOS es realmente ordenada. El código aquí se explica más abajo. Primero, se usa una estructura para contener detalles sobre los puertos que se desean usar como interfaz SPI.
+ expandir sourceview simple- typedef struct spi_slave_interface
- {
- reloj blk;
- en el puerto ss;
- en el puerto almacenado en búfer:8 mosi;
- puerto con búfer de salida:8 miso;
- en el puerto sclk;
- } spi_slave_interface;
Las líneas interesantes de arriba son las que se refieren a las variables de puerto mosi y miso. Se han declarado como puerto tipo:8. Si a las variables se les asignan direcciones de puerto de 1 bit, el dispositivo XMOS deserializará automáticamente el flujo de bits de 1 cable en valores de 8 bits.
Hace que el resto del código SPI sea realmente simple. Aquí está el código que administra la entrada de datos SPI desde Raspberry Pi:
+ expandir sourceview simple- void spi_slave_in_buffer (spi_slave_interface &spi_if, búfer de caracteres sin firmar [], int num_bytes)
- {
- datos int sin firmar;
- unsigned int vlen =0;
- clearbuf (spi_if.miso);
- clearbuf (spi_if.mosi);
- para (int i =0; i
- {
- spi_if.mosi:> datos;
- datos =datos <<24;
- búfer [i] =bitrev (datos);
- si (i ==2)
- {
- vlen =(((unsigned int) buffer [1]) <<8) | (unsigned int) buffer [2];
- if (vlen ==0)
- romper;
- }
- si (i> =vlen + 2)
- {
- romper;
- }
- }
- }
En el código anterior, puede ver que hay un bucle for, y dentro del bucle la línea spi_if.mosi:> data; se utiliza para leer 8 bits de información en la línea MOSI en la variable llamada datos.
Las siguientes dos líneas se utilizan para invertir los bits dentro del byte y luego los datos se almacenan en una matriz de búfer.
Las siguientes líneas necesitan una explicación; están relacionados con el protocolo deseado. Se pretendía crear un código de propósito general que pudiera usarse para muchas cosas, no solo XMP-1. Si la Raspberry Pi envía datos a la placa XMOS startKIT, la placa XMOS necesita saber cuántos bytes de datos esperar. Esto podría estar codificado de forma rígida, pero sería inflexible.
Se decidió utilizar un protocolo de "etiqueta (o tipo), longitud, valor" (TLV) muy simple. El primer byte que debe transmitir la Raspberry Pi es una etiqueta o identificador en el rango 0-255 (es decir, un byte). Depende del usuario decidir qué representan los valores. Por ejemplo, un valor de 1 podría significar "establecer la velocidad del motor" y un valor de 2 podría significar "establecer la intensidad del brillo de los faros". Los segundos dos bytes son un valor de 16 bits que indican cuántos bytes de valor (es decir, datos) deben seguir. Decidí limitar esto a 4kbyte (4096 bytes) que debería cumplir con muchos casos de uso, pero el valor real se puede cambiar ajustando una definición de BUFLEN en el código.
Por lo tanto, el número mínimo de bytes enviados en la interfaz SPI es tres (etiqueta y una longitud de 0x0000) y el máximo es 4099 que es una etiqueta y una longitud de 0x1000 (esto es 4096 en hexadecimal) y 4096 bytes de datos.
El protocolo se refinó ligeramente, por lo que un número de etiqueta impar significa que la Raspberry Pi espera una respuesta en la siguiente comunicación SPI que inicia después de que se completa el flujo de TLV actual, y un número de etiqueta par significa que la Raspberry Pi no espera respuesta. espalda.
Este es un protocolo muy básico, pero debería cumplir con muchos requisitos habituales. También se explica en la tabla a continuación donde el número azul es el índice de bytes SPI en el búfer receptor de 4099 bytes.
Volviendo al fragmento de código anterior, se puede ver que las siguientes líneas verifican el contenido del búfer [1] y del búfer [2] sobre la marcha mientras se reciben los datos SPI. Se espera que el contenido tenga la longitud que se muestra en el diagrama anterior (consulte el índice de búfer azul). Tan pronto como el código haya determinado la longitud restante, aceptará exactamente esa cantidad de bytes de datos, y luego la rutina se cerrará.
Eso cubre la entrada SPI a la placa XMOS en la línea MOSI. La salida SPI del dispositivo XMOS en la línea MISO funciona de manera similar, verificando la longitud simultáneamente en la línea MOSI sobre la marcha nuevamente, de modo que la función pueda salir tan pronto como se haya transferido el número solicitado de bytes.
Comunicación entre procesos
Ahora que se resolvió el SPI y se implementó un protocolo para intercambiar datos de longitud variable en cualquier dirección hasta 4096 bytes de longitud, se consideró el cuerpo principal del programa. Estaba claro que un núcleo XMOS estaría dedicado a manejar la tarea SPI, pero el resto del código puede necesitar residir en uno o más XMO Scores adicionales.
En la parte 1, se describió cómo las tareas se ejecutan en paralelo en diferentes núcleos XMOS y cómo las tareas pueden comunicarse entre sí al introducir valores en los canales. Existe otra forma de comunicación entre núcleos y utiliza el concepto de "transacciones a través de interfaces" en lugar de canales. Es más flexible porque puede enviar múltiples variables de diferentes tipos de un núcleo XMOS a otro. Los tipos de transacciones se definen de forma muy similar a un prototipo de función C. Todo esto se vuelve mucho más claro al mirar un ejemplo.
Por ejemplo, si una aplicación tenía una tarea que controlaba una pantalla, entonces una tarea de envío puede querer encender o apagar la pantalla, o puede querer trazar un píxel. La definición de interfaz para la comunicación entre los dos núcleos XMOS podría verse así:
+ expandir sourceview simple- interfaz program_display
- {
- retroiluminación vacía (estado int, color int); // tipo de transacción 1
- gráfico vacío (int x, int y, int color); // tipo de transacción 2
- };
La comunicación de la interfaz es unidireccional, por lo que si la pantalla quisiera enviar información como, por ejemplo, el estado de la pantalla táctil, entonces se necesitaría usar otra interfaz en la otra dirección. A partir de esto, queda claro que las interfaces tienen un cliente y un servidor. El diagrama aquí muestra dos núcleos XMOS (en violeta), dos interfaces (en gris) y la primera interfaz (llamada program_display) permite que ocurran dos tipos diferentes de transacciones (en azul) a través de la interfaz program_display.
Lo mejor de usar interfaces y tipos de transacciones es que, al igual que los prototipos de funciones C, puede tener valores de retorno y puede pasar referencias a variables, de modo que, aunque la comunicación siempre la inicia el extremo del cliente de la interfaz, la transferencia de datos puede ocurrir en ambos sentidos. Otra característica muy interesante que no se muestra en el diagrama es la capacidad del servidor para enviar una "notificación" al cliente. Esto puede ser una señal para que el cliente emita una transacción de la manera habitual, quizás para recuperar algunos datos. Esta función se utilizará en el código XMP-1. Por lo tanto, a continuación se explicará más información sobre cómo codificar exactamente las interfaces y enviar datos y notificaciones.
Diseño de la arquitectura IPC para manejar contenido SPI
Ya se ha descrito el manejo de la interfaz SPI. Ahora el contenido de los mensajes SPI debe presentarse a una tarea de una manera útil para su posterior procesamiento. Armado con el conocimiento sobre interfaces y transacciones, fue posible comenzar a asignar funcionalidad para separar núcleos XMOS y diseñar la comunicación entre procesos para llegar a un marco de propósito general que permitiría enviar contenido útil de mensajes desde el RPI al XMOS tablero y viceversa, y ser procesado.
El diagrama aquí muestra lo que se desarrolló (un diagrama similar al anterior, excepto que ahora hay una secuencia de tiempo de arriba a abajo).
Cuando la Raspberry Pi desea enviar un mensaje a la placa XMOS, el RPI construirá el mensaje en el formato TLV descrito anteriormente. Luego, la información se registra en el cable de señal MOSI (que se muestra en verde en la parte superior del diagrama de arriba). Simultáneamente, el dispositivo XMOS necesita enviar algo de vuelta, pero como aún no hay información para devolver, la línea MISO puede contener basura o todos los valores cero como se muestra en rosa. La función spi_process recopilará el mensaje en un búfer (una matriz de caracteres sin firmar) y luego iniciará una transacción en un núcleo XMOS de data_handler separado. El manejador de datos es responsable de procesar el contenido del mensaje y, opcionalmente, enviar información al núcleo spi_process XMOS, de modo que cualquier intercambio SPI posterior pueda enviar datos útiles a la Raspberry Pi en lugar de valores basura.
Los datos se pueden enviar entre spi_process y data_handler haciendo una copia del búfer. Sin embargo, es posible simplemente pasar un puntero a la memoria intermedia. Una forma de hacerlo es "mover" el control del puntero y las ubicaciones de la memoria intermedia de spi_process a data_handler. Una vez que data_handler termina con la inspección del mensaje, puede mover el control de regreso a spi_process usando la variable de retorno que es posible usar en las transacciones. Esta es la razón por la que el diagrama anterior tiene una transacción llamada array_data con un parámetro definido como puntero móvil y un valor de retorno definido como puntero móvil también. De esta manera, solo un núcleo XMOS tiene acceso a la memoria intermedia a la vez.
Estas son las interfaces que se utilizan:
+ expandir sourceview simple- interfaz to_rpi
- {
- código nulo (carácter c sin firmar);
- };
- interfaz from_rpi
- {
- unsigned char * movible array_data (unsigned char * movible bufp);
- };
El código spi_handler asigna espacio para un búfer y luego pasa el control del búfer al código data_handler usando la línea buf =c.array_data (move (buf)) que se muestra en el código aquí:
+ expandir sourceview simple- void
- spi_process (interfaz to_rpi server s, interfaz from_rpi client c)
- {
- almacenamiento de caracteres sin firmar [4099];
- unsigned char * movible buf =storage;
- …
- buf =c.array_data (mover (buf));
- …
- seleccionar
- {
- caso en código (carácter c sin firmar):
- si (c ==ENVIAR)
- {
- spi_slave_out_buffer (spi_sif, buf, 4099);
- }
- romper;
- }
- }
El código data_handler obtiene el control del búfer y luego, si se desea enviar alguna respuesta al RPI en una transacción SPI posterior, el búfer se llena con una respuesta. Finalmente, el control del búfer se devuelve al proceso spi_handler.
+ expandir sourceview simple- void
- data_handler (interfaz to_rpi client c, interfaz from_rpi server s)
- {
- seleccione
- {
- caso s.array_data (carácter no firmado * vp móvil) -> carácter no firmado * vq móvil:
- // vq contiene los datos de SPI. Podemos hacer lo que queramos con él aquí.
- // Cualquier respuesta también se construye aquí:
- vq [0] =0x22; // etiqueta
- vq [1] =0x00; // longitud
- vq [2] =0x00; // longitud
- vq =mover (vp); // devuelve el control del puntero a spi_process
- tosend =1;
- romper;
- }
- si (enviar)
- {
- c.code (ENVIAR); // send a code to spi_process so that it is aware there is data to send to RPI
- }
- }
Earlier it was mentioned that if an odd tag value was sent by the RPI then this would be an indication that the RPI expected a response message from the XMOS startKIT board on the subsequent SPI exchange. This is implemented by both the spi_process and data_handler making a note that a return message is expected if the first byte received is an odd value. Once data_handler has finished constructing the return message in the buffer memory it moves the buffer pointer back to the spi_process XMOS core and also sends a code transaction which could contain a message such as “ready to send”. The spi_process XMOS core is now ready for any subsequent SPI exchange. If the data_process doesn’t want to send any message back to the Raspberry Pi (for example if the tag was even valued) then the code transaction is not sent (or a different code could be sent such as “not ready to send”).
In the graphic diagram earlier you can see that the subsequent SPI exchange did transmit data back to the Raspberry Pi on the MISO wire.
To summarize, the spi_process and data_process present a fairly general-purpose capability to exchange data bidirectionally between the RPI and XMOS board.
Implementing PWM (servo_handler) on the startKIT
To test out the general purpose architecture, it was decided to use it to control many devices. The devices ended up being hobby servos because they require very little electrical interfacing effort – no H-bridge or transistor driver is needed – and the servo input wire can be directly connected to an XMOS output pin. I didn’t have many servos, so although the code implements 8 servo control, only two were used for XMP-1.
The code could be modified to provide DC motor control too (with a suitable external H-bridge circuit).
It was decided to use a single XMOS core to handle the eight servos. The diagram below shows the total of three XMOS processes used in the solution. The new addition is the servo_handler task which is shown on the right. This task has an array that stores the current servo values. As soon as the task starts up, the values are initialized to a centered value (or standstill for a continuous rotation servo) and then every microsecond the task wakes up to check if the servo PWM signal needs adjustment. If it does then the servo port output is toggled. After 20msec the process repeats.
For more detail:XMOS startKIT Building an XMOS and Raspberry Pi Robot XMP-1
Proceso de manufactura
- Comunicación MQTT entre NodeMCU y Raspberry Pi 3 B +
- Sensor de temperatura Python y Raspberry Pi
- Temperatura y humedad sencillas en Raspberry Pi
- Sensor de temperatura y luz Raspberry Pi
- Control de actuador y sensor Raspberry Pi
- Aeroponía con Raspberry Pi y sensor de humedad
- NUEVA FRAMBUESA PI 3 MODELO B + CARACTERÍSTICAS Y COMPRA
- Robot que usa Raspberry Pi y Bridge Shield
- BeagleBone y Raspberry Pi obtienen complementos FPGA
- Creación del kit de robot MonkMakes Raspberry Pi
- Robot de caja de CD Raspberry Pi