Problème de lecture d'un LSM9DS1 en I2C

Des infos, des conseils sur les bus DSI,CSI, I2C, SPI... du Raspberry Pi

Modérateur : Francois

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par spourre » lun. 13 mars 2017 22:14

Pinhapple a écrit :
Bud Spencer a écrit :J'avais d'ailleurs précisé dans les commentaires la nécessité de buffériser pour s'affranchir des temps d'écriture à chaque boucle ;)
Je viens de voir ton commentaire, c'est une bonne idée de "vider" le tableau dans ton fichier avec un thread !
Et du coup ça m'amène à une question : je ne peux pas utiliser 6 threads, chacun occupé à lire une valeur (accélération X, Y, Z, et rotation X, Y, Z) ?

EDIT : en modifiant le baudrate dans /boot/config.txt (ajout d'une ligne dtparam=i2c_baudrate=1200000), je passe à environ 1100 récupérations de 6 valeurs brutes par seconde, le tout avec mon programme en C et un MPU-6050. Du coup je vais retester avec le LSM9DS1 du Sense HAT pour voir ce que ça donne !
Un point ne me parait pas très clair: Les 6 threads, c'est pour lire le LSM ou pour lire le tableau dynamique et copier vers la carte SD ?

Étant un "vieux" formé au dernier millénaire, je ne maîtrise pas les threads mais leur ancêtre, le fork (je connais les différences). Ma répondre est donc à prendre avec circonspection, en attendant l'avis plus pertinent de Bud (ou d'un autre contributeur).

Dans les 2 cas, je pense que la multiplication des threads n'est pas de nature à optimiser. En effet, dans les 2 cas, nous avons :
1 seul "objet" en entré (le LSM ou le tableau dynamique (en RAM).
1 seul objet en sortie (le tableau dynamique ou le fichier sur la carte SD.

Il va donc falloir gérer les accès concurrents ce qui va introduire de la latence (gestion des verrous...).
Exemples:
-) accès au LSM via I2C:
Une lecture commence par une condition de départ, puis se termine par une condition de fin ( http://www.robot-electronics.co.uk/i2c-tutorial )
La thread va lire ses 2 octets et libérer le bus.

L'autre thread doit refaire une start condition, relire ses 2 octets, refaire une condition de fin.

Autant faire une thread d'acquisition qui fera sa condition de départ puis lira le N échantillons puis libérera le bus.

-) accès au tableau dynamique puis enregistrement sur carte SD:

Même s'il y a un fichier par grandeur mesurée, il il aura concurrence pour accéder au périphérique et au système de fichier.

BTW) Il faudra horodater les échantillons pour un traitement ultérieur.

Je pense qu'une thread de lecture du LSM, surtout en gérant par interruption, et une thread de vidage du tableau dynamique devrait permettre d'optimiser le processus.

Sylvain

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par Pinhapple » mar. 14 mars 2017 08:33

spourre a écrit :Un point ne me parait pas très clair: Les 6 threads, c'est pour lire le LSM ou pour lire le tableau dynamique et copier vers la carte SD ?
Ça aurait été pour faire l'acquisition des valeurs. Une fois ces valeurs dans une liste ou un tableau, je ne suis plus pressé de les écrire dans un fichier, donc plus besoin de thread.
spourre a écrit :Dans les 2 cas, je pense que la multiplication des threads n'est pas de nature à optimiser. En effet, dans les 2 cas, nous avons :
1 seul "objet" en entré (le LSM ou le tableau dynamique (en RAM).
1 seul objet en sortie (le tableau dynamique ou le fichier sur la carte SD.

Il va donc falloir gérer les accès concurrents ce qui va introduire de la latence (gestion des verrous...).
Exemples:
-) accès au LSM via I2C:
Une lecture commence par une condition de départ, puis se termine par une condition de fin ( http://www.robot-electronics.co.uk/i2c-tutorial )
La thread va lire ses 2 octets et libérer le bus.

L'autre thread doit refaire une start condition, relire ses 2 octets, refaire une condition de fin.

Autant faire une thread d'acquisition qui fera sa condition de départ puis lira le N échantillons puis libérera le bus.

-) accès au tableau dynamique puis enregistrement sur carte SD:

Même s'il y a un fichier par grandeur mesurée, il il aura concurrence pour accéder au périphérique et au système de fichier.

BTW) Il faudra horodater les échantillons pour un traitement ultérieur.

Je pense qu'une thread de lecture du LSM, surtout en gérant par interruption, et une thread de vidage du tableau dynamique devrait permettre d'optimiser le processus.
Merci pour le retour qui est comme toujours très instructif et complet ! Ayant trouvé de mon côté une solution qui me convient, je me pencherai sur les threads plus tard par curiosité, histoire de continuer à bricoler et à apprendre :)

D'ailleurs, mon histoire de réglage de baudrate a un peu fichu le boxon avec le Sense HAT, qui selon son humeur est resté soit constamment allumé (DEL en arc-en-ciel), soit complètement éteint (DEL éteintes) ; la commande i2cdetect -y 1 me renvoyait un tableau d'adresses entièrement rempli :o
J'ai donc revu le débit à la baisse pour le fixer à 400 kbits/s (fast-mode), et tout est redevenu normal ! :D
Pour info et histoire de compléter un peu le sujet, j'ai appris que le débit d'I2C peut être normal (100 kbits/s), fast-mode (400 kbits/s), fast-mode plus (1 Mbit/s), high-speed mode (3,4 Mbits/s), et enfin ultra-fast mode (5 Mbits/s, unidirectionnel).

Ce coup-ci je pense que c'est bon !
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par spourre » mar. 14 mars 2017 10:32

Pinhapple a écrit : Ça aurait été pour faire l'acquisition des valeurs. Une fois ces valeurs dans une liste ou un tableau, je ne suis plus pressé de les écrire dans un fichier, donc plus besoin de thread.
...
Merci pour le retour qui est comme toujours très instructif et complet ! Ayant trouvé de mon côté une solution qui me convient, je me pencherai sur les threads plus tard par curiosité, histoire de continuer à bricoler et à apprendre :)
...
D'ailleurs, mon histoire de réglage de baudrate a un peu fichu le boxon avec le Sense HAT, qui selon son humeur est resté soit constamment allumé (DEL en arc-en-ciel), soit complètement éteint (DEL éteintes) ; la commande i2cdetect -y 1 me renvoyait un tableau d'adresses entièrement rempli :o
J'ai donc revu le débit à la baisse pour le fixer à 400 kbits/s (fast-mode), et tout est redevenu normal ! :D
Pour info et histoire de compléter un peu le sujet, j'ai appris que le débit d'I2C peut être normal (100 kbits/s), fast-mode (400 kbits/s), fast-mode plus (1 Mbit/s), high-speed mode (3,4 Mbits/s), et enfin ultra-fast mode (5 Mbits/s, unidirectionnel).

Ce coup-ci je pense que c'est bon !
Je confirme donc mon analyse, trop de threads sur une même ressource,

Comme déjà écrit, on adopte les réponses à l'interlocuteur et cela ne concerne pas que le niveau mais aussi le degré de curiosité .
En I2C, il n'y a pas de compatibilité ascendante. Un composant qui donné pour un mode, saura répondre dans les modes moins rapides, pas l'inverse.
Normalement, il ne réagit pas. Dans le cas de la Sense HAT, il faut décortiquer le schéma pour comprendre mais il me semble que la matrice de LED (et le joystick) est commandée par un micro-proc (Atmel) qui peut perdre les pédales.

A tous ces modes, vous pouvez ajouter le mode d'adressage. Historiquement sur 7 bits + 1 bit qui détermine si on l'adresse en lecture/écriture (R/W) le mode d'adressage a été étendu afin de tenir compte du nombre élevé de circuits I2C.
Pour certains, l'adressage est gravé dans le silicium, d'autres disposent de 3 bits de poids faible pour pouvoir en mettre plus d'un sur le bus.

Attendez tout de même l'intervention de Bud pour compléter mon analyse sur les threads.
quand vous aurez un peu de temps, n'hésitez pas à faire une fiche synthèse de tout ce que vous aurez accumulé d'informations vérifiées, entre cette discussion, vos recherches et vos essais. Ceci vous permettra de mettre au clair et de structurer ces nouvelles connaossances.

Bon courage

Sylvain

Bud Spencer
Raspinaute
Messages : 445
Enregistré le : lun. 15 août 2016 21:38

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par Bud Spencer » mar. 14 mars 2017 10:35

Concernant les 6 threads, mon raisonnement est exactement le même que celui de Spourre. Sans entrer dans les détails, multiplier le nombre de process, n’a aucun intérêt puisque tu travailles sur la même liaison qui de toutes façon ne sais gérer qu’une seule transaction à la fois. Si tu créais 6 threads différents, il faudrait gérer la concurrence et de fait, tu aurais pratiquement toujours 5 threads en attente de la libération de la ligne (et de l’autorisation de prendre la main sur les données partagées) par le sixième. Au final, plus de code, plus d’espace mémoire occupée, beaucoup plus de complexité et finalement de moins bonnes performance.

Ceci dit, les threads ont aussi leurs avantages et deviennent même rapidement indispensable dans bien des cas. J’avais fait un petit article là-dessus sur le blog Framboise314. Ça vaut ce que ça vaut, et j’avais juste essayé de démontrer leur utilité à travers l’exemple simple du clignotement d’une led : http://www.framboise314.fr/penser-threa ... rogrammes/

Pour le Fast-Mode I2C, c’est ce que je t’expliquais au début. Après il faut faire attention. Tous les composants I2C ne gère pas ce mode. Il faut aussi savoir que beaucoup de gens se sont plaint de soucis de cohérence des données et d’effondrement de la vitesse de transmission en Fast-Mode avec le PI, il va donc falloir que tu surveilles ce point.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par spourre » mar. 14 mars 2017 11:28

Bud Spencer a écrit :Concernant les 6 threads, mon raisonnement est exactement le même que celui de Spourre. Sans entrer dans les détails, multiplier le nombre de process, n’a aucun intérêt puisque tu travailles sur la même liaison qui de toutes façon ne sais gérer qu’une seule transaction à la fois. Si tu créais 6 threads différents, il faudrait gérer la concurrence et de fait, tu aurais pratiquement toujours 5 threads en attente de la libération de la ligne (et de l’autorisation de prendre la main sur les données partagées) par le sixième. Au final, plus de code, plus d’espace mémoire occupée, beaucoup plus de complexité et finalement de moins bonnes performance.

Ceci dit, les threads ont aussi leurs avantages et deviennent même rapidement indispensable dans bien des cas. J’avais fait un petit article là-dessus sur le blog Framboise314. Ça vaut ce que ça vaut, et j’avais juste essayé de démontrer leur utilité à travers l’exemple simple du clignotement d’une led : http://www.framboise314.fr/penser-threa ... rogrammes/

Pour le Fast-Mode I2C, c’est ce que je t’expliquais au début. Après il faut faire attention. Tous les composants I2C ne gère pas ce mode. Il faut aussi savoir que beaucoup de gens se sont plaint de soucis de cohérence des données et d’effondrement de la vitesse de transmission en Fast-Mode avec le PI, il va donc falloir que tu surveilles ce point.
Merci de cette confirmation.

Il peut encore faire la synthèse des 2 discussions (celle-ci et celle sur le GPIO) pour suivre ton idée:
déclencher une interruption par un signal d'horloge externe et, activer la thread de lecture du capteur. Ça pourrait avoir de la gueule et être pratiquement déterministe si le SOC n'est pas trop chargé et si l'interruption est non masquable (NMI) ou de priorité élevée (reste que tout ça est quand même en user land).

Cela ne m'étonne qu'à moitié, il y a la théorie et la pratique. atteindre des vitesses élevées ne suffit pas si les signaux se dégradent (ex: l'horloge SPI). De toute manière, le Raspberry est une petite bête très sympa, peu coûteuse mais ne vise pas à concurrencer des plateformes de développement professionnelles qui coûtent les yeux de la tête + un bras + la peau des couill* :twisted:

Je crois que maintenant il va pouvoir se mettre au boulot et revenir nous faire un beau compte-rendu.
A+

Sylvain

Bud Spencer
Raspinaute
Messages : 445
Enregistré le : lun. 15 août 2016 21:38

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par Bud Spencer » mar. 14 mars 2017 15:43

Pour moi il y a plusieurs approches possibles. Le problème, c’est que comme c’est un projet ‘secret défense' :lol:, c’est à lui de décidé laquelle utiliser en fonction du réel besoin.

On a bien compris que la vitesse d’acquisition était primordiale mais pour moi, ce n’est qu’une annexe technique qui ne suffit pas à déterminer un choix de méthode à utiliser.

Vouloir récupérer un maximum de données dans un laps de temps est une chose, mais qu’est ce qui doit primer ? Le nombre de données ou le temps ? Simplifié en 2 questions cela donnerait :

Je veux n valeurs dans un laps de temps le plus court possible
Ou
Je veux le plus de valeurs possibles sur un laps de temps t

Ça se ressemble beaucoup, mais pour moi c’est fondamentalement différent. La seule chose qui resterait éventuellement la même dans les deux cas, c’est la procédure unitaire de récupération des données qui doit être optimum, mais le reste du ‘programme’ serait totalement diffèrent.

On peut aller encore plus loin dans la réflexion, exemple :

Quel que soit la méthode choisie, imaginons que j’ai un simple capteur de vitesse qui mesure justement la vitesse d’un déplacement quelconque. Sauf qu’à partir de mes résultats, je dois pouvoir calculer avec précision les accélérations entre chaque point de mesure. Dans ce cas, ce n’est pas la quantité de données ni le temps total d’acquisition qui devra primer, mais plutôt la précision des intervalles entre chaque mesure. Dans ce cas l’approche ‘développement’ sera encore différentes des deux précédentes.

Alors bien sûr, quand on monte un projet sur un PI à 40 balles avec des capteurs que nos amis chinois nous refourguent au prix du cours du grain de riz, on relativise, on ‘moyenise’, on extrapole et on s’estime déjà heureux d’avoir accès à autant de technologie pour s’amuser. Ce qui n’empêche pas que le bon choix des méthodes permet de limiter les compromis qui comme chacun le sait ne font pas de bons programmes mais seulement des programmes ‘satisfaisants’ ;)
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par spourre » mar. 14 mars 2017 16:56

Ça ne devrait pas te surprendre, mais je partage ton point de vue (non, on est pas des clones, l'admin peut le certifier, il a nos @IP :twisted: ).
Pour moi, les choix techniques (architecture, structure du programme ...) interviennent en dernier, quand on a parfaitement analysé le problème à résoudre.
Il est évident, que dans un cadre hobbyiste ou pédagogique, le critère financier impose une forte contrainte et peut limiter les ambitions (sauf à avoir un ami très riche :roll: ).
Avec le Raspberry, moi le premier, on fait l'inverse et on cherche ce que l'on peut bien en faire. Ce n'est pas une démarche condamnable mais on se condamne à en subir tous les compromis. Encore faut-il en avoir conscience.
Dans le cas de Pinhapple dont le profil indique "étudiant" (comme les Talibans ?), en admettant que le projet soit lié à son domaine d'études, ça peut même le conduire à (se) poser les bonnes questions.

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par Pinhapple » mer. 15 mars 2017 08:22

Bud Spencer a écrit :Le problème, c’est que comme c’est un projet ‘secret défense' :lol:
spourre a écrit :comme les Talibans ?
Tu m'as tué ! :lol:

Suffit de demander ! C'est pour une plate-forme accueillant des radars, pendant mon stage de fin d'études. ;)

Par contre, avoir modifié le baudrate doit gêner l'ATTINY88 qui pilote la matrice de DEL et le joystick, puisque ceux-ci ne sont plus utilisables avec l'API Sense HAT, et impossible d'y accéder en I2C à son adresse 0x46 (le i2cdetect -y 1 indique UU à cette adresse, ce qui indique apparemment qu'elle est déjà occupée)... :?
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par spourre » mer. 15 mars 2017 10:21

Pinhapple a écrit :
spourre a écrit :comme les Talibans ?
Tu m'as tué ! :lol:

Suffit de demander ! C'est pour une plate-forme accueillant des radars, pendant mon stage de fin d'études. ;)

Par contre, avoir modifié le baudrate doit gêner l'ATTINY88 qui pilote la matrice de DEL et le joystick, puisque ceux-ci ne sont plus utilisables avec l'API Sense HAT, et impossible d'y accéder en I2C à son adresse 0x46 (le i2cdetect -y 1 indique UU à cette adresse, ce qui indique apparemment qu'elle est déjà occupée)... :?

Sérieusement, j'avais pensé à une éolienne
Etes-vous sur le même projet que:
viewtopic.php?f=57&t=3171
On a du lui faire peur, il n'est jamais revenu :twisted:

Votre projet m'intéresse parce que, en background, j'ai un projet qui mûrit, pour mes activités de radioamateur en portable isolé:
Un panneau solaire piloté pour la poursuite du soleil. Le faire en analogique serait très facile mais je veux qu'il soit totalement autonoime: On le pose parterre et il se cale tout seul puis fait le tracking en site/Azimuth. Ceci implique de le doter d'un module GPSZ (localiation) et de compenser le dévers (pas de mise à niveau).

C'est peut-être un peu compliqué pour cette fonction seule mais, derrière ce projet, il y a un autre projet qui se dessine: L’asservissement d'une antenne (petite parabole, antenne panneau, ...) sur un satellite (géostationnaire ou défilant), sur un mobile lent (camping-car, bateau...). Regardez le coût d'une simple antenne TV satellite pour un camping-car.

Le principe étant de ne pas chercher à stabiliser la plateforme mais à prendre en compte ses mouvements sur les trois axes (lacet, tangage et roulis) pour piloter la monture motorisée sur 2 axes seulement.

Sylvain

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Problème de lecture d'un LSM9DS1 en I2C

Message par Pinhapple » mer. 15 mars 2017 11:28

spourre a écrit :Sérieusement, j'avais pensé à une éolienne
Etes-vous sur le même projet que:
viewtopic.php?f=57&t=3171
On a du lui faire peur, il n'est jamais revenu :twisted:
Ah, ça aurait pu être ça, en effet ! :)
Non, pas du tout le même projet ! Mais j'étais tombé sur ce sujet en cherchant des informations ;)
spourre a écrit :Votre projet m'intéresse parce que, en background, j'ai un projet qui mûrit, pour mes activités de radioamateur en portable isolé:
Je ne pense pas avoir votre niveau en RPi et autres, mais si je peux aider, même en vous faisant des retours sur mon projet de mon côté, n'hésitez pas ! ;)
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

Répondre

Retourner vers « Les BUS interfaces »