Club robotique de Sophia-Antipolis

Accueil > Essais > Robots et kits > LEGO Mindstorms > La carte d’extension BrickPi

La carte d’extension BrickPi

lundi 16 décembre 2013, par Eric P.

Lors d’un de mes récents échanges téléphoniques avec lui à l’occasion d’une commande professionnelle, Yassine de Génération Robots m’a gentiment proposé de me faire parvenir une BrickPi en vue de la tester et de vous en faire un petit compte-rendu. Dont acte.

BrickPi : Kesako ?

Pour ceux qui ne suivent pas assidument l’actualité Raspberry Pi, la BrickPi est une carte créée par Dexter Industries et ayant pour vocation d’offrir à la Raspberry Pi une interface matérielle avec les capteurs et moteurs LEGO Mindstorms (NXT ou EV3). Le couple BrickPi + RasPi se substitue donc à la brique programmable LEGO afin d’offrir plus de puissance et de souplesse en termes d’outils de programmation. Le projet est open source et open hardware et est le fruit d’un financement collaboratif [1].

Je ne vais pas vous en dire plus, car tout est expliqué sur le site Web de Dexter Industries, à la section dédiée à ce produit. A noter que les pages n’ont à ce jour pas été totalement mises à jour, et les photos (ainsi que certains textes et commentaires) font référence à une version préliminaire, un peu moins bien dotée en nombre de ports.

L’objet peut s’acheter et il existe en deux versions, dont la seule différence est la section alimentation. La version la moins chère utilise un régulateur linéaire, alors que la version dite "Advanced Power" utilise un régulateur à découpage, ce qui procure une plus grande autonomie des batteries grâce à un meilleur rendement.

La BrickPi en solo
La BrickPi installée sur la RasPi

A noter que je n’ai pas monté l’ensemble dans le "boîtier" fourni, et ai laissé la RasPi sur le socle provenant de son boitier, car je n’ai pour l’instant pas de RasPi à dédier aux projets LEGO Mindstorms (mais ça viendra ;)

Côté logiciel, trois versions de la bibliothèque d’interfaçage sont proposées :
 C/C++
 Python
 Scratch

Cette dernière option attire l’attention, car on touche ici un sujet potentiellement concurrentiel de l’environnement LEGO, qui a le gros défaut de ne pas tourner sous notre système à l’effigie du manchot (lors de ma tentative de l’installer sous Wine, l’installeur s’est figé peu après le début).

Tout cela fait donc du BrickPi un objet qui aiguise la curiosité, et la proposition de Yassine est tombée à pic.

Premières impressions

Je vous fais grâce du déballage et de l’assemblage du kit du boitier, abondamment décrits par ailleurs. Nous ne sommes pas ici pour tirer à la ligne à grands coups de copier/coller du boulot des autres ;)

Le produit est de bonne facture, mais présente quelques petits défauts de conception, sans incidence aucune sur le fonctionnement. J’ai jugé utile de les mentionner, car partout ailleurs vous ne lirez certainement que des louanges, alors autant jouer le rôle du méchant.

Taille de la carte

Elle est un peu bâtarde, en ce sens que si la largeur est la même, elle est plus courte que la RasPi d’environ 5 mm. Pourquoi diantre ? Utiliser exactement les mêmes dimensions aurait permis d’avoir un peu plus d’espace sur la carte, ce qui n’aurait pas été du luxe par endroits (cf plus loin). Cela aurait été plus esthétique en outre, même si ce genre de point n’est pas d’une importance capitale.

Différence de longueur entre les deux cartes

Liaison mécanique

Cette carte présente le défaut de la plupart des cartes d’extension pour la RasPi, à l’exception des produits de AB Electronics [2] : la liaison mécanique repose entièrement sur le header GPIO, et n’exploite pas la présence des deux trous de fixation apparus avec la RasPi modèle B. C’est d’autant plus gênant avec les cartes comportant des connecteurs, sur lesquels des efforts vont inévitablement être appliqués lors de la connexion et déconnexion de câbles, efforts qui vont se reporter sous forme de bras de levier au niveau du header.

Si vous utilisez la BrickPi à demeure sur une RasPi dédiée à la construction de robots LEGO Mindstorms, je conseille d’ajouter un point de fixation au moyen d’un morceau de double face épais au niveau du connecteur Ethernet. Si vous utilisez un modèle de RasPi sans Ethernet, eh bien tant pis, car le socket USB ne présente pas suffisamment de surface en commun avec la BrickPi.

En l’absence de fixation complémentaire entre les deux cartes, il est plus prudent de tenir l’ensemble par la BrickPi et non pas la RasPi lors de l’insertion ou du retrait de câbles LEGO. Ces derniers étant d’ailleurs particulièrement rigides, les contraintes appliquées au header peuvent ne pas être négligeables. Vous aurez été prévenus.

Risques de contacts électriques

Connecteur Ethernet
Connecteur USB

Comme on peut le voir sur les photos ci-dessus, la carte repose sur les embases Ethernet et USB et est au contact de cette dernière. Certes les soudures des embases RJ ont été de toute évidence aplanies, et leurs picots de fixation mécanique constituent une entretoise séparatrice, mais si d’aventure le vernis épargne au niveau de l’embase USB venait à être gratté du fait de frottements, je ne donne pas cher du résultat.

L’adjonction d’un petit morceau de double-face fin entre l’embase USB et le PCB de la BrickPi est fortement conseillée par sécurité, et contribuera également au maintien (cf point précédent).

Fabrication du PCB

[EDIT 17/12] Suite au commentaire posté par un visiteur, il se peut que ce que j’ai pris pour un défaut de fabrication au niveau de l’alignement des perçages soit en réalité fait à dessein. J’ai préféré laisser le texte initial cependant, des fois que d’autres que moi s’étonnent de la chose, ne connaissant pas la méthode proposée par Sparkfun. Ce qui induit en erreur ici, c’est que même la sérigraphie est décalée et pas uniquement les trous. Ce n’est pas le cas dans la méthode citée en référence, car son auteur a pris soin de ne décaler que les perçages, mais en laissant la sérigraphie intacte. Merci en tout cas à Nicolas d’avoir apporté cette précision, et d’avoir signalé cette technique originale.

C’est un point de détail sans incidence, mais ça ne fait pas très pro : les trous en ligne des emplacements des headers optionnels ne sont pas alignés. Ca sent d’ailleurs le copier/coller d’un pattern comportant le défaut.

Il s’agit :
 des headers 2x3 ISP,
 du header 1x3 de sélection de l’ATMega à flasher,
 du header 1x6 du câble de programmation.

Mauvais alignement des trous

J’ai cependant vérifié que le léger décalage n’empêchait pas le montage des headers mâles qui vont bien, pour ceux qui souhaiteraient les installer.

Un autre détail qui ne fait pas très pro non plus : le connecteur 2 points pour l’alimentation déborde de la carte :

Position un peu rock’n’roll du connecteur d’alimentation

Ce n’est certes pas dramatique, mais ça fait un peu bricolé, d’autant plus que le débord est inférieur à la différence de longueur entre la BrickPi et la RasPi. Il y avait donc largement de la marge pour le faire rentrer comme il se doit si les dimensions des deux cartes avaient été identiques.

Pour être complet, je citerai également la grosse capa implantée de travers, mais on va dire que c’est un problème pendant le transport, car j’ai réussi à la redresser.

La capa avait dû fêter Nouvel An avant l’heure :)

Conclusion

Bon, rien de rédhibitoire en définitive, et ces quelques défauts de jeunesse sans conséquence seront probablement rectifiés dans des révisions futures de la BrickPi. Je sais, je suis un pinailleur, mais je l’assume.

La structure de la carte

De manière surprenante, le site de la BrickPi n’est pas très loquace sur le sujet, et il faut étudier le schéma électronique de la carte pour avoir toutes les informations.

Schéma électronique BrickPi
Dester Industries

Comme on peut le voir d’un simple coup d’oeil, la carte est propulsée par deux ATMega328. Pourquoi deux ? Tout simplement parce qu’ils se partagent à parts égales les entrées-sorties. Ah oui, mais il y a 5 entrées, ce qui n’est pas très divisible par 2. La réponse est que l’entrée 5 (baptisée "fast I2C") est reliée en direct aux signaux I2C du connecteur GPIOs de la RasPi, et n’est pas du tout gérée par les ATMega.

Les deux autres chips sont les ponts en H pour le pilotage des moteurs. Il s’agit de SN754410, pouvant commuter jusqu’à 1A sous 36V. A noter qu’aucune diode de roue libre (non incluses dans le SN754410) n’est visible sur le PCB ni sur le schéma de la carte. Pas trop rassurant si d’aventure on imaginait piloter autre chose que les moteurs LEGO avec ces sorties.

Communications BrickPi - RasPi

La communication entre les deux cartes se fait par la liaison série dont la vitesse est portée à 500kbits. Comment je le sais ? En ayant été lire le code source de la bibliothèque côté RasPi.

Originalité de l’architecture : il s’agit d’une liaison multi-drop, les deux ATMega étant connectée en parallèle [3] au niveaux des signaux Rx/Tx. Les échanges sont synchrones et à l’initiative de la RasPi. Un mécanisme d’adressage inclus en tête de la structure de donnée envoyée permet de sélectionner l’ATMega destinataire et duquel on attendra la réponse en retour.

Il est d’ailleurs possible d’empiler plusieurs BrickPi, et d’augmenter ainsi les capacités en termes de capteurs et d’actionneurs. Il faudra reprogrammer les EEPROM des ATMega additionnels, de manière à y stocker les adresses à utiliser pour y causer. Chaque ATMega va en effet lire son adresse dans son EEPROM au démarrage.

Le protocole est assez simple :

 les échanges de données se font au moyen d’une structure qui contient en entrée les données fournies par les capteurs et en sortie les consignes pour les moteurs

 cette structure est transférée globalement au moyen d’une unique primitive de la bibliothèque (BrickPiUpdateValues dans la version Python) qui transmet les consignes moteurs et reçoit les lectures des capteurs.

Efficace et sans complication inutile. D’ailleurs le code source de la version Python de la bibliothèque fait seulement 539 lignes, commentaires et lignes blanches comprises.

Configuration de la RasPi

L’utilisation de la BrickPi nécessite une distribution Wheezy modifiée. Le plus simple est d’en récupérer l’image sur le site de Dexter, qui indique également comment modifier une Wheezy dans le cas où on souhaite travailler à partir d’une image spécifique, contenant par exemple vos propres aménagements.

Les principales adaptations portent sur :
 la modification de la clock de l’UART afin de pouvoir utiliser une vitesse de communication plus élevée (cf plus haut)
 l’installation du support de l’I2C
 la libération du port série, assigné par défaut à une console
 la désactivation de la console série lors du boot, sinon les ATMega de la BrickPi ne vont pas comprendre ce qu’on leur veut.
 l’installation de libraires Python complémentaires (pySerial, rpi, smbus)

Rendez-vous par conséquent sur la page dédiée du site Dexter pour cette étape.

Rien de particulier à signaler, la procédure se déroule comme décrit sur le site Web. Il n’y a qu’à suivre les étapes sans se poser de question.

Réglages maison

En ce qui me concerne, j’ai désactivé le lancement de l’environnement de bureau, car j’utilise toujours la RasPi en mode headless. Et de toute manière je vois mal un écran HDMI raccordé à un robot LEGO ;) Et puisqu’on n’utilise plus l’environnement graphique, on peut également modifier la partition mémoire, en allouant le minimum proposé à la carte graphique. Toutes ces opérations se font sans difficulté au moyen de l’outil raspi-config.

Programmation

Je me suis intéressé à la programmation en Python dans un premier temps, et ce pour plusieurs raisons :
 c’est très pratique pour des essais, du fait du côté interactif du langage
 puisque la BrickPi fait partie de l’arsenal des outils pédagogiques pour l’initiation des plus jeunes ou des débutants à la robotique, on ne va pas les faire fuir d’entrée de jeu en les jetant en pâture au compilateur C/C++
 j’aime bien Python (mais ça vous le saviez peut-être déjà :)

L’installation du support Python de la BrickPi est décrit très simplement sur le site Dexter. Là encore il suffit de saisir les quelques commandes indiquées et tout est prêt pour vos expérimentations. Je ne vais donc pas gaspiller des octets et de la bande passante à répéter bêtement ce qui est déjà écrit ailleurs. Bon, ok, c’est en Anglais, mais une commande Linux reste la même quelle que soit la langue maternelle du programmeur, et cela vous permettra de faire quelques progrès en langues étrangères si vous en avez besoin.

A la lecture de la documentation, ça n’a pas l’air bien compliqué, en vertu du principe de communication présenté un peu plus haut. Plutôt que de faire ici de la paraphrase, je vous engage à étudier les quelques exemples très simples inclus dans le téléchargement de l’environnement BrickPi. Vous le constaterez par vous-même : il n’y a pas de quoi prendre peur.

Alimentation

Avant de commencer à faire bouger des choses, je vous suggère de vous procurer une alimentation 9V et de la relier au connecteur d’alimentation de la BrickPi. Oubliez la pile 9V qu’on voit sur les diverses illustrations, à moins que vous n’en ayez eu un camion gratuit pour Noël ou que vous ayez des actions chez Duracell et consorts. Ce connecteur permet d’alimenter la BrickPi, elle-même fournissant le 5V à la RasPi.

Premiers essais

Le plus simple pour vérifier que tout cela fonctionne est de se rendre dans le répertoire Sensor_Examples. Il y a là une collection de programmes simples illustrant les principes généraux de la mise en oeuvre de la BrickPi, depuis le clignotement des deux LEDs embarquées jusqu’à l’utilisation des capteurs évolués Dexter, en passant bien entendu par les moteurs et capteurs LEGO.

A noter que l’exécution des programmes de test des LEDs requiert d’être su (ou de l’invoquer avec la commande sudo) car celles-ci sont directement reliées aux GPIOs, dont l’accès n’est par défaut autorisé qu’à root. Les autres fonctionnalités faisant appel à la communication série entre les deux cartes, elles sont accessibles en tant qu’utilisateur standard.

Tout fonctionne comme prévu, en tout cas pour ce que j’ai pu tester, ne disposant pas de tous les types de capteurs illustrés. Cependant, pour éviter de ne plus avoir d’écho ni de newline après l’exécution des programmes utilisant curses (comme la démo d’un bras piloté par le clavier), il faut ajouter un appel à curses.endwin() à la fin du programme.

Allons un peu plus loin

Il n’y a curieusement aucune démo concernant le positionnement des moteurs, ce qui est quand même une propriété intéressante des moteurs LEGO. Pourtant une fonction motorRotateDegree existe dans le module BrickPi, mais elle est absente de la version C de la bibliothèque. On se serait attendu à ce que ce genre de fonction soit implémentée directement sur les ATMega de la BrickPi afin d’assurer un asservissement correct. Du coup, on peut se demander quelles en sont les performances, car le mécanisme de dialogue avec la RasPi ne va faire qu’aggraver les latences.

En fait, on ne se le demande plus du tout dès lors qu’on a fait quelques essais sous environnement interactif Python par exemple. La précision de position est tout sauf acceptable et de plus est très dépendante de la période de rafraîchissement (paramétrable à l’appel de la fonction).

La situation ne s’arrange guère si on essaye de gérer deux moteurs de cette manière, et du coup il n’est plus envisageable de faire du pilotage de robot, ni même d’envisager sereinement une ligne droite. Ce phénomène est amplifié par le fait que le mode brake des moteurs n’est pas implémenté, comme le montre l’étude du code source du firmware, dans lequel aucune mise en configuration correspondante du pont en H n’est faite. Par conséquent, pour tenter d’arrêter net le moteur, la fonction rotateMotorDegree donne une impulsion en sens inverse en fin de mouvement pour tenter de le bloquer à la position cible. Le problème est que le succès de ce type de stratégie est tout sauf garanti, et que le moteur restant en roue libre après, aucun maintien de position n’est possible (que ce soit pour un bras ou pour un robot mobile).

La vidéo ci-dessous illustre ceci, le script correspondant étant inclus à la suite.


#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import BrickPi as bp
 
import time
 
MOTOR_A = bp.PORT_A
MOTOR_B = bp.PORT_B
motors = [MOTOR_A, MOTOR_B]
 
bp.BrickPiSetup()
for motor in motors:
    bp.BrickPi.MotorEnable[motor] = 1
bp.BrickPiSetupSensors()
 
bp.BrickPiUpdateValues()
 
speed = 200
angle = 360
 
try:
    rotation_dir = 1
    while True:
        bp.motorRotateDegree([speed] * 2, [angle * rotation_dir] * 2, motors)
        rotation_dir = -rotation_dir

        time.sleep(0.5)
 
except KeyboardInterrupt:
    print('\nTerminating...')
    for motor in motors:
        bp.BrickPi.MotorSpeed[motor] = 0
    bp.BrickPiUpdateValues()

On peut au passage constater sur la vidéo que l’erreur de position est assez catastrophique :
 la consigne de rotation donnée aux moteurs est de 360 degrés
 l’erreur observée est non constante et atteint parfois quasiment un quart de tour, avec rotation sur l’élan :/

Bon, vous l’aurez compris, la gestion des moteurs ne m’a pas convaincu. On peut espérer que cela est dû au fait que le produit vient de sortir, et que très rapidement la communauté proposera quelque chose de plus abouti en termes de logiciel. Votre serviteur aimerait bien y contribuer, mais il passe son temps à courir après le temps (comme beaucoup de monde malheureusement). Dans tous les cas cela ne pourra se faire que par l’implémentation de l’asservissement directement sur les ATMega, de manière à ne plus dépendre de la fréquence de lecture effectuée par l’application, et à simplifier le code de celle-ci.

[EDIT] Ayant repris les tests le lendemain de la rédaction de ce qui précède, j’ai constaté que le port A ne fonctionne plus : le moteur ne bouge plus. Serait-ce l’absence de diodes de roue libre évoquée plus haut qui a frappé ? Et d’ailleurs, en testant les autres ports moteur non encore utilisés, j’ai aussi constaté que la lecture de l’encodeur sur le port D ne marche pas non plus. Décidément, cette carte commence à accumuler les mauvais points en termes de qualité.

Et les capteurs ?

Intéressons-nous maintenant aux capteurs.

La liste des matériels supportés est pour le moment assez limitée :
 les capteurs classiques NXT : lumière (en mode passif et actif), contact, ultra-son, couleur LEGO
 les capteurs Dexter (charité bien ordonnée commence par soi-même ;)
 l’interface gamepad Playstation de Mindsensors

Pour le reste, débrouillez vous. Rien pour les capteurs HiTechnic ou Mindsensors. OK, ça viendra certainement très prochainement, au fur et à mesure que des bonnes volontés feront évoluer le produit. La bonne nouvelle, c’est que les capteurs que j’ai testés (contact, lumière et ultra-son) fonctionnent. Ceci étant je n’ai pas eu la patience de les essayer sur tous les ports...

Je n’ai pas essayé le 5ème port capteur, car il ne passe de toute manière pas par les ATMega, puisqu’encore une fois il est directement connecté sur les signaux I2C de la RasPI. Attention par conséquent à ne pas mettre n’importe quoi dessus, car il n’y a même pas de level shifter sur ces lignes, et si vous y envoyez du 5V, eh bien tant puis pour la RasPi :/ Ils ont été un peu faibles sur ce coup, et en fait ce 5ème connecteur n’est là que pour faire illusion, et ne peut en aucun cas être considéré comme un 5ème port capteur NXT.

Conclusion

Nous voici arrivés au terme de ce galop d’essai avec la BrickPi.

Je ne vais pas vous raconter d’histoire, et comme vous vous en doutez, je ne considère pas dans sa forme actuelle que ce soit un produit intéressant. En tout cas, j’estime qu’il ne vaut pas les 60 Euros que coûte la version de base (et les 90 Euros de celle qui nous a été confiée). Je n’ai pas trop d’inquiétude sur tout ce qui concerne la partie soft, car il suffit que des gens motivés et compétents s’y attellent pour que les choses bougent rapidement. Mais j’ai par contre plus de doutes sur les faiblesses hardware, qui seront plus délicates à corriger. Si je reprenais la notation d’une des revues Linux que je lis régulièrement, je lui donnerais seulement 2 geeks sur 5, avec la mention "idée intéressante, mais peut mieux faire".

Mon conseil sera donc : gardez un oeil sur le produit, mais dépêchez-vous d’attendre qu’il mûrisse avant de jeter votre dévolu dessus. Même pour un geek c’est limite, car il y a du travail à faire pour le finaliser. D’ailleurs, très honnêtement et sans être méchant, la lecture du code Python est assez édifiante : il s’agit d’une traduction mot à mot du source C (lui même pas hyper génial), qui donne l’impression que son auteur avait découvert Python une demi-heure avant d’écrire son code.

Pour ce qui est de concurrencer une brique NXT ou EV3 à des fins d’initiation (c’est pourtant le but de l’interface Scratch qui est proposée), il ne faut pas rêver. A suivre cependant de près, car le concept est intéressant.


[1KickStarter et consorts

[2suite à une suggestion de votre serviteur d’ailleurs

[3un comble pour une liaison série :)

Vos commentaires

  • Le 23 janvier 2015 à 15:06, par Florian En réponse à : La carte d’extension BrickPi

    Bonjour,
    J’aimerai savoir si une alternative est possible pour l’alimentation en alimentant la Raspberry indépendamment de la BrickPi.
    Je n’ai trouvé aucune information à ce sujet. Peut-être en savez-vous davantage.
    Merci.

    Répondre à ce message

  • Le 17 décembre 2013 à 08:23, par Nicolas Schodet En réponse à : La carte d’extension BrickPi

    Merci pour la revue très intéressante :)

    Concernant les headers non alignés, je pense que c’est voulu. J’ai vu ça dans les bibliothèques de Sparkfun, l’idée est de coincer le connecteur afin d’en faciliter la soudure : https://www.sparkfun.com/tutorials/114.

    • Le 17 décembre 2013 à 10:53, par Eric P. En réponse à : La carte d’extension BrickPi

      C’est la première fois que j’entends parler de cette technique, mais on en apprend tous les jours (c’est ça qui est intéressant dans notre activité)

      Ceci dit, ça ne fonctionne pas car les headers ne tiennent pas mieux (j’ai fait le test). Et pour ce qui est du look, ça ne fait pas très industriel malgré tout.

      On va donc octroyer le bénéfice du doute et dire que c’est "on purpose" :)

    Répondre à ce message

Un message, un commentaire ?

modération a priori

Attention, votre message n’apparaîtra qu’après avoir été relu et approuvé.

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.