Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

XMOS startKIT :Création d'un robot XMOS et Raspberry Pi XMP-1

Présentation

Le XMOS startKIT de Farnell (ou Newark) est une plate-forme de processeur à très faible coût (12 £ TTC) qui fonctionne bien avec le Raspberry Pi. Ensemble, il est possible de construire des applications robotiques presque sans soudure.

Le XMOS startKIT est une carte de la taille d'une carte de crédit avec une puce XMOS dessus avec plusieurs « cœurs XMOS » qui peuvent être programmés en C. La technologie XMOS permet aux choses de fonctionner en parallèle à grande vitesse avec une faible gigue. Ce sont exactement les caractéristiques qui pourraient être idéales pour les applications robotiques.

Avec du code à exécuter sur la carte XMOS startKIT et sur le Raspberry Pi (RPI), les cartes sont utilisées pour construire une simple plate-forme mobile compacte (je vais l'appeler XMP, XMOS Mobile Platform au lieu d'un robot à partir de maintenant dans l'esprit XMOS de tout faire précéder de 'X').

Bien que le XMP-1 ne soit pas vraiment un robot tant qu'il n'a pas quelques capteurs et plus de programmation, il pourrait être étendu à l'avenir pour des expériences de robotique. Le XMP-1 utilise du matériel standard à faible coût et aucun outil exotique au-delà d'un tournevis, d'un coupe-fil et d'une pince.

Cet article couvre la communication entre les cartes RPI et XMOS à l'aide d'une interface d'interface périphérique série (SPI) et explique comment construire le XMP-1 et le contrôler à partir d'un navigateur Web.

La vidéo montre ici XMP-1 en train d'apprendre un itinéraire ; la première tentative d'utilisation ! Il bénéficierait d'une meilleure interface utilisateur. Le XMP-1 peut se déplacer assez rapidement, mais j'y suis allé doucement ici à basse vitesse. Sur la droite se trouve le contrôle du navigateur et en bas se trouve la sortie de la console, générant simplement des messages de maintien et d'état pour voir ce qui se passe.

La vidéo suivante ci-dessous montre le XMP-1 essayant de rejouer l'itinéraire et provoquant souffrance et douleur en cours de route. Mes servos à rotation continue bon marché (qui sont utilisés pour entraîner les roues) n'étaient pas très bons, et le XMP-1 n'a pas encore de capteurs.

Un peu plus de détails

Cet article est en fait la partie 2 de certaines expériences XMOS startKIT. La partie 1 contient l'introduction XMOS, la terminologie, l'architecture et un guide de démarrage rapide avec des exemples de programmes. Si vous êtes intéressé par la technologie, il peut être utile de suivre d'abord la partie 1, afin que cette partie 2 ait plus de sens. Cette partie 2 est destinée à construire un cadre simple pour les communications à haute vitesse entre le Raspberry Pi et la carte XMOS startKIT. Le cadre doit être suffisamment général pour pouvoir être utilisé pour de nombreux projets (la robotique n'était pas mon intention). Le XMP-1 n'est vraiment qu'un sous-produit, dans le but de tester les communications entre la carte Raspberry Pi et XMOS. Il est enregistré ici au cas où cela serait utile. (Remarque, il y a aussi une partie 3 intitulée XMOS startKIT :XMOS et Raspberry Pi Oscilloscope XAE 1000 qui réutilise la capacité SPI discutée dans ce post, et présente comment utiliser le convertisseur analogique-numérique (ADC) qui est présent dans la puce XMOS , et comment effectuer des graphiques en temps réel dans un navigateur Web).

Si vous êtes uniquement intéressé par la construction et l'utilisation de XMP-1, vous pouvez simplement prendre le code au bas de l'article, le compiler et le stocker dans Flash (comme décrit dans la partie 1) sur la carte XMOS startKIT et le Raspberry Pi, et suivez simplement les sections qui décrivent l'assemblage du matériel XMP-1, en sautant tout autre contenu ici. Si vous souhaitez contrôler n'importe quel matériel à l'aide du Raspberry Pi et d'un navigateur Web, une partie du code ici peut être réutilisé. Mais, pour tirer le meilleur parti de la combinaison Raspberry Pi et XMOS startKIT, le reste des informations ici peut être utile si vous débutez avec le startKIT.

Présentation de la solution – Matériel et logiciel

Voici une photo du XMP-1 terminé en cours de chargement. Pour une utilisation en extérieur, j'ai utilisé un appareil de type hotspot 802.11 (MiFi), exécutant le navigateur sur un téléphone mobile.

Le diagramme ci-dessous montre la disposition approximative des bits et des pièces vue de l'arrière du XMP-1. Vous pouvez voir que c'est assez basique - XMP-1 n'était qu'une expérience rapide.

Le Raspberry Pi (RPI) est utilisé pour gérer toutes les activités du réseau. Il exécute un petit serveur Web et la plupart du code est écrit en JavaScript sur une plate-forme Node.js. Le RPI communique les vitesses de contrôle du moteur (en fait, des servos à rotation continue ont été utilisés pour le XMP-1) via une interface série (SPI) à la carte XMOS startKIT. Le XMOS startKIT est chargé de fournir des signaux de modulation de largeur d'impulsion (PWM) aux moteurs.

Le RPI est connecté au réseau à l'aide d'un adaptateur USB WiFi 802.11.

Le schéma de câblage complet est montré ici. Le matériel et la construction sont décrits plus loin.

Le schéma ci-dessous montre le logiciel qui sera implémenté sur le RPI et sur le startKIT. Cela semble beaucoup, mais ce n'est pas le cas et peut être décomposé en petites parties qui seront décrites plus loin. Comme mentionné, l'intégralité du code source se trouve au bas de cet article, il peut donc être utilisé sans aucune modification si vous le souhaitez.

En bref, le bloc vert gère l'interaction Web et détermine la vitesse et la direction des moteurs en fonction de l'entrée de l'utilisateur. Le bloc vert fournit une page Web (index.html) à l'utilisateur qui intègre l'interface utilisateur. Le programme xmos_servo est un petit logiciel écrit en C qui traduit la vitesse/direction souhaitée en octets de données d'interface périphérique série qui sont envoyés au startKIT. Le logiciel startKIT est divisé en trois parties qui s'exécutent simultanément sur des cœurs XMOS distincts. Le spi_process convertit les signaux SPI en données stockées dans un tableau. Le code data_handler inspecte le tableau pour décider quoi faire (la seule conclusion qu'il tire aujourd'hui est de manipuler les servos). Le processus servo_handler envoie un flux d'impulsions aux servos, afin qu'ils puissent tourner à la vitesse souhaitée. Tous ces blocs sont expliqués plus en détail ci-dessous.

Interface périphérique série (SPI)

SPI repose sur quatre fils appelés SS, SCLK, MISO et MOSI et une affectation de maître et d'esclave pour les deux appareils impliqués dans la communication. Dans le cas des cartes RPI et XMOS, le RPI est le périphérique maître et est responsable de la génération du signal d'horloge. Le RPI transmet des données sur le fil MOSI et reçoit des données sur le fil MISO. Cela signifie que l'interface SPI peut transférer des données de manière bidirectionnelle en même temps. En pratique, si des données unidirectionnelles sont requises, le signal MOSI ou MISO peut être ignoré en fonction de la direction d'intérêt.

La capture d'écran de l'oscilloscope ici (signaux individuels et décodage SPI automatisé d'un oscilloscope Tektronix MSO2024B) montre un exemple de communication SPI utilisant le Raspberry Pi. SPI peut être configuré de plusieurs manières; vous pouvez voir dans cet exemple que trois octets de données ont été transférés du maître (RPI) à l'esclave (carte XMOS) et qu'ils étaient 0x02, 0x00 et 0x10, et soit aucune donnée ou 0x00, 0x00, 0x00 a été transféré du esclave au maître simultanément.

Le fil SS est un signal de sélection de puce (actif bas). Le RPI a deux broches sur son connecteur à 26 voies qui pourraient être utilisées pour SS ; ils sont représentés entourés de bleu dans le schéma ci-dessous, notés CE0 et CE1. Cela signifie que le RPI peut communiquer avec deux appareils esclaves SPI si vous le souhaitez. Dans ce cas, une seule des broches CE a été utilisée - j'ai choisi CE1.

contrôle des servomoteurs Hobby

Les servomoteurs Hobby génèrent un mouvement basé sur un signal d'entrée. Ils tournent généralement moins d'un tour complet. Habituellement, un servo de loisir tournera dans une plage d'environ 180 degrés. L'arbre de sortie peut être connecté à (disons) des liaisons pour faire tourner les roues complètement à gauche ou complètement à droite (ou quelque chose entre les deux) en fonction du signal d'entrée.

Le schéma ci-dessous montre les composants internes d'un servo de passe-temps typique (tiré de ce site). Sur la gauche (en bleu) se trouve un moteur à courant continu conventionnel. Il est beaucoup démultiplié, et l'on voit à droite l'arbre final relié à un bras bleu qui pourrait être relié à un mécanisme de direction de roue par exemple. Sous l'arbre final se trouve un potentiomètre qui fournit des informations sur la position exacte de l'arbre final. Un servo de loisir est donc un système en boucle fermée et peut s'auto-corriger si le bras est accidentellement déplacé de la position souhaitée.

Les servos Hobby ont généralement trois connexions; 0V, 5V et Signal. Le fil de signal est une entrée numérique vers le servo et il nécessite un signal PWM. La taille de la largeur d'impulsion détermine l'angle auquel l'arbre se déplacera. Le signal PWM doit se répéter toutes les 20 ms et une largeur d'impulsion de 1,5 ms entraînera le déplacement de l'arbre vers une position centrée. Une largeur de 1 ms déplacera complètement le servo dans une direction, et une largeur de 2 ms déplacera complètement le servo dans l'autre sens (ci-dessous, il y aura quelques traces de servocommande d'oscilloscope).

Il existe un type de servo modifié appelé servo à « rotation continue ». Il s'agit d'un servomoteur modifié où le potentiomètre est retiré avec toutes les butées de fin de course, et le circuit est persuadé de penser que le servomoteur est toujours en position centrée. L'envoi de PWM avec une largeur d'impulsion autre que 1,5 ms fera tourner le mécanisme dans le sens horaire ou antihoraire à une vitesse qui dépend de la largeur d'impulsion. Le XMP-1 utilise deux servos hobby à rotation continue, un pour chaque roue. Ils ne constituent pas un moyen optimal d'obtenir un mouvement contrôlé (le XMP-2 utilisera des moteurs à balais CC) car ils sont utilisés à des fins différentes de l'intention d'origine des servomoteurs de loisir, mais ils ont l'avantage de pouvoir être contrôlés par un contrôleur numérique. signal logique et ils ne nécessitent aucun circuit externe en pont en H.

Les câbles d'asservissement Hobby peuvent être codés par couleur différemment selon le fabricant. Habituellement, le fil central est rouge et passe à +5V. Le fil noir ou marron est en 0V. Le fil blanc ou jaune est l'entrée du signal PWM.

Démarrer le développement – ​​Connecter les cartes

Afin de développer le logiciel, le RPI et le startKIT ont été connectés à l'aide d'un câble plat et d'un connecteur IDC - ceux-ci peuvent être assemblés à l'aide d'un étau ou achetés prêts à l'emploi. Pour une version auto-assemblée, il vaut la peine d'acheter un connecteur IDC supplémentaire à utiliser comme connecteur de débogage au centre du câble, pour faciliter la vie lors de la vérification des signaux avec un multimètre ou un oscilloscope.

Implémentation de SPI (spi_process) sur le XMOS startKIT

L'utilisation de l'environnement de développement XMOS (xTIMEcomposer) a été couverte dans la première partie. Les captures d'écran ci-dessous montrent la version Windows de xTIMEcomposer, mais la version Linux semble identique (et peut-être que la version Mac peut également être similaire).

À ce stade, vous pouvez cliquer avec le bouton droit sur la bibliothèque de fonctions esclave SPI dans le laboratoire xSOFTip et importer la bibliothèque dans l'espace de travail. Je ne suis pas un expert de xTIMEcomposer, donc je l'utilise probablement mal ici, mais le code source et le fichier d'en-tête de la bibliothèque sont apparus dans un dossier séparé dans l'explorateur de projet (encerclé en bleu ci-dessous) :

Les fichiers devaient se trouver dans le dossier spi-test (afin qu'ils apparaissent comme indiqués encerclés en vert ci-dessus) afin d'y parvenir, j'ai copié manuellement les fichiers spi_slave.h et spi_slave.xc du dossier module_spi_slave/src dans le spi-test dossier /src à l'aide de l'explorateur Windows.

Le logiciel utilise le concept de ports pour contrôler la sortie ou lire l'entrée. Il existe un mappage entre ces ports logiques et le mappage physique vers la broche sur la puce. Les mappages peuvent être modifiés dans certaines combinaisons (voir la figure 3 dans le document PDF Introduction aux ports XS1).

Les ports d'entrée/sortie sur les appareils XMOS peuvent avoir une largeur de 1, 4, 8, 16 ou 32 bits. Lors de la conception avec la pièce, vous souhaiterez peut-être attribuer certaines fonctions à des ports 1 bit, ou d'autres fonctions à des ports multibits, et la figure 3 sera donc très utile pour déterminer quels ports et broches utiliser.

Avec le code esclave SPI maintenant dans le fichier spi-test/src, ce code a été légèrement modifié. Le code de la bibliothèque suppose que les ports utilisés pour l'interface SPI sont tous des ports 1 bit, tandis que la broche Raspberry Pi SPI SS (CE1) est connectée à un port 32 bits sur la carte XMOS. La figure 8 du document PDF du manuel du matériel startKIT est illustrée ci-dessous. Au centre en vert, vous pouvez voir l'en-tête 2 × 13 voies qui se connecte entre la carte XMOS et le Raspberry Pi. À gauche et à droite en bleu se trouvent les noms de broches physiques sur la puce (X0D0,, X0D11, etc.). Les valeurs surlignées des broches sont les numéros de port logiques. P1A, P1D et ainsi de suite sont des ports à bit unique. P32A1 est le premier chiffre binaire d'un port 32 bits

De nombreuses modifications ont été apportées à la bibliothèque SPI et l'intégralité du code est jointe à la publication, donc seuls quelques extraits de code seront décrits ici, il n'est pas nécessaire de copier/coller, le code complet joint à la fin de cette publication peut être utilisé.

L'interface SPI sur le périphérique XMOS est initialisée comme indiqué ici. C'est expliqué plus loin.

+ élargir la sourceview plain
  1. void spi_slave_init(spi_slave_interface &spi_if)
  2. {
  3.     int clk_start ;
  4.     set_clock_on(spi_if.blk );
  5.     configure_clock_src(spi_if.blk, spi_if.sclk );
  6.     configure_in_port(spi_if.mosi, spi_if.blk );
  7.     configure_out_port(spi_if.miso, spi_if.blk, 0) ;
  8.     start_clock(spi_if.blk);
  9.     retour ;
  10. }

Comme mentionné dans l'article de la partie 1, les E/S peuvent être cadencées à l'intérieur et à l'extérieur du périphérique XMOS à des heures précises. Dans le code ci-dessus, la fonction set_clock_on (définie dans le fichier d'en-tête XMOS xs1.h) est utilisée pour activer l'un des mécanismes de synchronisation intégrés dans la puce XMOS. Le schéma ci-dessous (issu du document Introduction aux ports XS1) montre ce mécanisme en jaune. La fonction configure_clock_src permet de sélectionner une horloge externe (indiquée en bleu sur le schéma). Il sera connecté à la broche SCLK du Raspberry Pi. Les fonctions configure_in_port et configure_out_port sont utilisées pour lier les ports au mécanisme de synchronisation. Les signaux MOSI et MISO (affichés en vert ci-dessous) sont configurés pour être liés au mécanisme d'horloge.

La façon dont les données série sont gérées sur les appareils XMOS est vraiment soignée. Le code ici est expliqué plus en détail ci-dessous. Premièrement, une structure est utilisée pour contenir des détails sur les ports que l'on souhaite utiliser comme interface SPI.

+ élargir la sourceview plain
  1. typedef struct spi_slave_interface
  2. {
  3.     horloge blk ;
  4.     dans le port ss ;
  5.     dans le port tampon :8 mosi ;
  6.     port hors tampon : 8 miso ;
  7.     dans le port sclk ;
  8. } spi_slave_interface ;

Les lignes intéressantes ci-dessus sont celles qui font référence aux variables de port mosi et miso. Ils ont été déclarés comme type port:8. Si les variables se voient attribuer des adresses de port 1 bit, le périphérique XMOS désérialisera automatiquement le flux de bits 1 fil en valeurs 8 bits.

Cela rend le reste du code SPI vraiment simple. Voici le code qui gère l'entrée des données SPI depuis le Raspberry Pi :

+ élargir la sourceview plain
  1. void spi_slave_in_buffer(spi_slave_interface &spi_if, unsigned char buffer[], int num_bytes)
  2. {
  3.     données int non signées ;
  4.     unsigned int vlen=0 ;
  5.     clearbuf(spi_if.miso );
  6.     clearbuf(spi_if.mosi);
  7.     for (int i = 0; i < num_bytes; i++)
  8.     {
  9.         spi_if.mosi :> données ;
  10.         data=data<<24 ;
  11.         buffer[i]=bitrev(données );
  12.         if (i==2)
  13.         {
  14.             vlen=(((unsigned int)buffer[1])<<8) | (unsigned int)buffer[2] ;
  15.             if (vlen==0)
  16.                 pause ;
  17.         }
  18.         if (i >= vlen+2)
  19.         {
  20.             pause ;
  21.         }
  22.     }
  23. }

Dans le code ci-dessus, vous pouvez voir qu'il y a une boucle for, et dans la boucle la ligne spi_if.mosi :> data; est utilisé pour lire 8 bits d'information sur la ligne MOSI dans la variable appelée data.

Les deux lignes suivantes sont utilisées pour retourner les bits dans l'octet, puis les données sont stockées dans un tableau tampon.

Les quelques lignes suivantes ont besoin d'explications; ils sont liés au protocole souhaité. Il était destiné à créer du code à usage général qui pourrait être utilisé pour de nombreuses choses, pas seulement XMP-1. Si le Raspberry Pi envoie des données à la carte XMOS startKIT, la carte XMOS doit savoir combien d'octets de données attendre. Cela pourrait être codé en dur, mais ce serait inflexible.

Il a été décidé d'utiliser un protocole très simple « tag (ou type), longueur, valeur » (TLV). Le premier octet que le Raspberry Pi doit transmettre est une balise ou un identifiant compris entre 0 et 255 (c'est-à-dire un octet). C'est à l'utilisateur de décider ce que les valeurs représentent. Par exemple, une valeur de 1 pourrait signifier « régler la vitesse du moteur » et une valeur de 2 pourrait signifier « régler l'intensité de la luminosité des phares ». Les deux autres octets sont une valeur de 16 bits qui indiquent combien d'octets de valeur (c'est-à-dire de données) doivent suivre. J'ai décidé de limiter cela à 4 Ko (4096 octets), ce qui devrait répondre à de nombreux cas d'utilisation, mais la valeur réelle peut être modifiée en ajustant une définition BUFLEN dans le code.

Par conséquent, le nombre minimum d'octets envoyés sur l'interface SPI est de trois (tag et une longueur de 0x0000) et le maximum est de 4099 qui est un tag et d'une longueur de 0x1000 (c'est 4096 en hexadécimal) et 4096 octets de données.

Le protocole a été légèrement affiné, de sorte qu'un numéro de balise impair signifie que le Raspberry Pi attend une réponse dans la communication SPI suivante qu'il initie une fois le flux TLV en cours terminé, et un numéro de balise pair signifie que le Raspberry Pi n'attend aucune réponse retour.

Il s'agit d'un protocole très basique mais il doit répondre à de nombreuses exigences habituelles. Il est également expliqué dans le tableau ci-dessous où le nombre bleu est l'index d'octet SPI dans le tampon de réception de 4099 octets.

En revenant à l'extrait de code précédent, on peut voir que les quelques lignes suivantes vérifient le contenu du tampon[1] et du tampon[2] à la volée pendant la réception des données SPI. Le contenu devrait avoir la longueur indiquée dans le diagramme ci-dessus (voir l'index de tampon bleu). Dès que le code a déterminé la longueur du reste, il accepte exactement ce nombre d'octets de données, puis la routine se termine.

Cela couvre l'entrée SPI vers la carte XMOS sur la ligne MOSI. La sortie SPI du périphérique XMOS sur la ligne MISO fonctionne de manière similaire, en vérifiant à nouveau la longueur simultanément sur la ligne MOSI à la volée, de sorte que la fonction puisse se terminer dès que le nombre d'octets demandé a été transféré.

Communication inter-processus

Maintenant que SPI était compris et qu'un protocole avait été mis en œuvre pour échanger des données de longueur variable dans les deux sens jusqu'à 4096 octets, une certaine attention a été accordée au corps principal du programme. Il était clair qu'un noyau XMOS serait dédié à la gestion de la tâche SPI, mais le reste du code devra peut-être résider dans un ou plusieurs scores XMO supplémentaires.

Dans la partie 1, il a été décrit comment les tâches s'exécutent en parallèle sur différents cœurs XMOS et comment les tâches peuvent communiquer entre elles en poussant des valeurs dans des canaux. Il existe une autre façon de communiquer entre les cœurs et elle utilise le concept de « transactions via des interfaces » plutôt que des canaux. Il est plus flexible car vous pouvez envoyer plusieurs variables de types différents d'un cœur XMOS à un autre. Les types de transaction sont définis un peu comme un prototype de fonction C. Tout cela devient beaucoup plus clair en regardant un exemple.

Par exemple, si une application avait une tâche qui contrôlait un affichage, une tâche d'envoi peut vouloir activer ou désactiver l'affichage, ou elle peut vouloir tracer un pixel. La définition de l'interface pour la communication entre les deux cœurs XMOS pourrait ressembler à ceci :

+ élargir la sourceview plain
  1. interface program_display
  2. {
  3.     void backlight(int state, int color) ; // transaction type 1
  4.     void plot(int x, int y, int color); // type de transaction 2
  5. } ;

La communication d'interface est unidirectionnelle, donc si l'écran voulait envoyer des informations telles que (disons) l'état de l'écran tactile, une autre interface devrait être utilisée dans l'autre sens. De là, il est clair que les interfaces ont une extrémité client et serveur. Le diagramme ici montre deux cœurs XMOS (en violet), deux interfaces (en gris) et la première interface (appelée program_display) permet à deux types de transactions différents de se produire (en bleu) sur l'interface program_display.

L'avantage de l'utilisation d'interfaces et de types de transaction est que, tout comme les prototypes de fonction C, vous pouvez avoir des valeurs de retour et vous pouvez passer des références à des variables, de sorte que même si la communication est toujours initiée par l'extrémité cliente de l'interface, le transfert de données peut se produire dans les deux sens. Une autre caractéristique très intéressante non représentée sur le schéma est la possibilité pour le serveur de pouvoir envoyer une « notification » au client. Cela peut être un signal pour le client d'émettre une transaction de la manière habituelle, peut-être pour récupérer des données. Cette fonctionnalité sera utilisée dans le code XMP-1. Ainsi, plus d'informations sur la façon exacte de coder les interfaces et d'envoyer des données et des notifications seront expliquées plus loin.

Concevoir l'architecture IPC pour gérer le contenu SPI

La gestion de l'interface SPI a déjà été décrite. Maintenant, le contenu des messages SPI doit être présenté à une tâche de manière utile pour un traitement ultérieur. Armé des connaissances sur les interfaces et les transactions, il a été possible de commencer à allouer des fonctionnalités pour séparer les cœurs XMOS et à concevoir la communication inter-processus pour arriver à un cadre à usage général qui permettrait d'envoyer du contenu de message utile du RPI au XMOS conseil d'administration et vice-versa, et être traité.

Le diagramme ici montre ce qui a été développé (un diagramme similaire au précédent, sauf qu'il y a maintenant une séquence temporelle de haut en bas).

Lorsque le Raspberry Pi souhaite envoyer un message à la carte XMOS, le RPI construira le message au format TLV décrit précédemment. L'information est ensuite cadencée sur le fil de signal MOSI (affiché en vert en haut du schéma ci-dessus). Simultanément, le périphérique XMOS doit renvoyer quelque chose, mais comme il n'y a pas encore d'informations à renvoyer, la ligne MISO peut contenir des déchets ou toutes les valeurs zéro comme indiqué en rose. La fonction spi_process collectera le message dans un tampon (un tableau de caractères non signés), puis initiera une transaction vers un noyau XMOS data_handler séparé. Le data_handler est chargé de traiter le contenu du message et éventuellement de renvoyer des informations au noyau XMOS de spi_process, de sorte que tout échange SPI ultérieur puisse renvoyer des données utiles au Raspberry Pi au lieu de valeurs parasites.

Les données pourraient être envoyées entre spi_process et data_handler en faisant une copie du tampon. Cependant, à la place, il est possible de simplement passer un pointeur vers la mémoire tampon. Une façon de procéder consiste à « déplacer » le contrôle des emplacements de pointeur et de mémoire tampon de spi_process vers data_handler. Une fois que data_handler a terminé l'inspection du message, il peut ramener le contrôle à spi_process en utilisant la variable de retour qu'il est possible d'utiliser dans les transactions. C'est pourquoi le diagramme ci-dessus a une transaction appelée array_data avec un paramètre défini comme un pointeur mobile et une valeur de retour définie comme un pointeur mobile également. De cette façon, un seul cœur XMOS a accès à la mémoire tampon à la fois.

Voici les interfaces utilisées :

+ élargir la sourceview plain
  1. interface to_rpi
  2. {
  3.     void code(unsigned char c);
  4. } ;
  5. interface from_rpi
  6. {
  7.     unsigned char* movable array_data(unsigned char* movable bufp);
  8. } ;

Le code spi_handler alloue de l'espace pour un tampon, puis passe le contrôle du tampon au code data_handler en utilisant la ligne buf=c.array_data(move(buf)) indiquée dans le code ici :

+ élargir la sourceview plain
  1. vide
  2. spi_process(interface to_rpi server s, interface from_rpi client c)
  3. {
  4.  stockage de caractères non signé[4099] ;
  5.   unsigned char* movable buf=storage ;
  6.   …
  7.   buf=c.array_data(move(buf));
  8.   …
  9.   sélectionnez
  10.   {
  11.     case s.code(unsigned char c) :
  12.       si (c==ENVOYER)
  13.       {
  14.         spi_slave_out_buffer(spi_sif, buf, 4099 );
  15.       }
  16.       pause ;
  17.   }
  18. }

Le code data_handler obtient le contrôle du tampon, puis si une réponse doit être envoyée au RPI lors d'une transaction SPI ultérieure, le tampon est rempli avec une réponse. Enfin, le contrôle du tampon est renvoyé au processus spi_handler.

+ élargir la sourceview plain
  1. vide
  2. data_handler(interface to_rpi client c, interface from_rpi server s)
  3. {
  4.   sélectionnez
  5.   {
  6.       case s.array_data(unsigned char* movable vp) -> unsigned char* movable vq :
  7.          / vq contient les données de SPI. Ici, nous pouvons faire ce que nous aimons.
  8.          // Toute réponse est établie ici aussi :
  9.          vq[0]=0x22 ; // balise
  10.          vq[1]=0x00 ; // longueur
  11.          vq[2]=0x00 ; // longueur
  12.          vq=move(vp); // passez le contrôle du pointeur à spi_process
  13.          tosend=1 ;
  14.          pause ;
  15.      }
  16.   si (pour envoyer)
  17.   {
  18.     c.code(SEND) ; // envoyer un code à spi_process afin qu'il sache qu'il y a des données à envoyer à RPI
  19.   }
  20. }

Plus tôt, il a été mentionné que si une valeur de balise impaire était envoyée par le RPI, cela indiquerait que le RPI attendait un message de réponse de la carte XMOS startKIT lors de l'échange SPI suivant. Ceci est implémenté à la fois par le spi_process et le data_handler en notant qu'un message de retour est attendu si le premier octet reçu est une valeur impaire. Une fois que data_handler a fini de construire le message de retour dans la mémoire tampon, il déplace le pointeur de tampon vers le noyau XMOS de spi_process et envoie également une transaction de code qui pourrait contenir un message tel que « prêt à envoyer ». Le noyau XMOS spi_process est maintenant prêt pour tout échange SPI ultérieur. Si le data_process ne veut renvoyer aucun message au Raspberry Pi (par exemple si le tag a même été valorisé), alors la transaction de code n'est pas envoyée (ou un code différent pourrait être envoyé tel que "pas prêt à envoyer") .

Dans le diagramme graphique ci-dessus, vous pouvez voir que l'échange SPI ultérieur a transmis des données au Raspberry Pi sur le fil MISO.

Pour résumer, spi_process et data_process présentent une capacité assez générale pour échanger des données de manière bidirectionnelle entre la carte RPI et XMOS.

Implémentation de PWM (servo_handler) sur le startKIT

Pour tester l'architecture à usage général, il a été décidé de l'utiliser pour contrôler de nombreux appareils. Les appareils ont fini par être des servomoteurs de loisir car ils nécessitent très peu d'effort d'interfaçage électrique - aucun pont en H ou pilote de transistor n'est nécessaire - et le fil d'entrée du servo peut être directement connecté à une broche de sortie XMOS. Je n'avais pas beaucoup de servos, donc bien que le code implémente 8 servocommandes, seuls deux ont été utilisés pour le XMP-1.

Le code peut être modifié pour fournir également un contrôle de moteur à courant continu (avec un circuit de pont en H externe approprié).

Il a été décidé d'utiliser un seul cœur XMOS pour gérer les huit servos. Le diagramme ci-dessous montre le total des trois processus XMOS utilisés dans la solution. Le nouvel ajout est la tâche servo_handler qui est affichée à droite. Cette tâche a un tableau qui stocke les valeurs d'asservissement actuelles. Dès que la tâche démarre, les valeurs sont initialisées à une valeur centrée (ou à l'arrêt pour un servo à rotation continue) puis toutes les microsecondes la tâche se réveille pour vérifier si le signal PWM du servo a besoin d'être ajusté. Si c'est le cas, la sortie du port servo est basculée. Après 20 ms, le processus se répète.

Pour plus de détails :XMOS startKIT Construction d'un robot XMOS et Raspberry Pi XMP-1


Processus de fabrication

  1. Communication MQTT entre NodeMCU et Raspberry Pi 3 B+
  2. Capteur de température Python et Raspberry Pi
  3. Température et humidité faciles sur Raspberry Pi
  4. Capteur de température et de luminosité Raspberry Pi
  5. Contrôle du capteur et de l'actionneur Raspberry Pi
  6. Aéroponie avec Raspberry Pi et capteur d'humidité
  7. NEW RASPBERRY PI 3 MODEL B + CARACTÉRISTIQUES ET ACHAT
  8. Robot utilisant Raspberry Pi &Bridge Shield
  9. BeagleBone et Raspberry Pi bénéficient de modules complémentaires FPGA