Page 6 sur 9

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

Posté : jeu. 9 mars 2017 16:50
par spourre
Pinhapple a écrit : ....
Et je lance le programme avec

Code : Tout sélectionner

./ProgD
Cette dernière commande me renvoie l'erreur suivante :

Code : Tout sélectionner

./ProgD: error while loading shared libraries: liblsm9ds1.so: cannot open shared object file: No such file or directory
J'imagine que j'ai un ou plusieurs arguments à ajouter à ma commande ?
Pour être dans les mêmes conditions, en natif sur un Raspberry, j'ai tout fait sur ma pauvre bête, sans filtre de la cross-compilation.

1) J'ai téléchargé à partir du dépôt dont vous donner le lien.
2) j'ai fait le make et j'obtiens un répertoire pour les includes et un répertoire pour la lib.
3) je suis descendu dans le répertoire example et j'ai fait le make pour obtenir l'exemple.

Résultat: Même ,erreur d’exécution que vous.

Toujours sur mon pauvre Pi B+, j'ai décidé de mettre un peu d'ordre dans ce binz.
J'ai donc copié la bibliothèque dans un endroit plus standard (/usr/lib)
J'ai copié les fichiers d’entêté dans /usr/include
j'ai relancé ldconfig pour prendre tout cela en compte:

Code : Tout sélectionner

$ cd ./lib
$ sudo cp  ./*.so  /usr/lib/.
$ cd ../include
$ sudo cp  ./*.h  /usr/include/.
$ sudo  ldconfig
Après, je suis retourné dans le sous-répertoire example et j'ai compilé à la main (pas besoin du Makefile dans ce cas)
La compile se passe bien et, quand je lance l'exemple, j'obtiens bien la réponse attendue car je n'ai pas de gyro sur le port i2c (j'ai pris gcc car l'exemple n'a rien de C++ et le Makefile définit bien CC=gcc !):

Code : Tout sélectionner

$ cd ./example
$ gcc  -llsm9ds1 -Wall -O2 LSM9DS1_Basic_I2C.cpp -o LSM9DS1_Basic_I2C
$ ./LSM9DS1_Basic_I2C
$ Failed to communicate with LSM9DS1.
Sylvain

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

Posté : jeu. 9 mars 2017 19:55
par destroyedlolo
Pinhapple a écrit :

Code : Tout sélectionner

./ProgD
Cette dernière commande me renvoie l'erreur suivante :

Code : Tout sélectionner

./ProgD: error while loading shared libraries: liblsm9ds1.so: cannot open shared object file: No such file or directory
J'imagine que j'ai un ou plusieurs arguments à ajouter à ma commande ?
Ben parce que ca revient à ce que je disais au début :
un .so est un "objet partagé" qui sera liée dynamiquement au moment de l'exécution. En d'autres termes, il devra TOUJOURS etre accessible après la compilation.
Donc, plusieurs possibilités :
  1. compiler la version statique la librairie (qui donne un '.a') : la librairie est liée directement DANS l’exécutable et donc tu n'en a plus besoins après. C'est utile pour faire des exécutables "portable" dans le sens que tu peux l'exécuter sur n'importe quelle autre machine de meme type sans te soucier que les librairies soient installées (typiquement, les versions FireFox dites "portables")
  2. Placer la librairie dans un répertoire standard comme /usr/local/lib, /usr/local/lib/lib ou /usr/local/lib/lib64 suivant comment to système est configuré (/usr/lib* est réservé aux librairies du système, il est donc déconseillé de le modifier)
  3. Ajouter le répertoire ou se trouve ta librairie dans la variable LD_LIBRARY_PATH genre

    Code : Tout sélectionner

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pi/Desktop/
  4. indiquer le répertoire par l'option -rpath de gcc (très très crade)
Si on veut faire propre, la librairie n'a clairement rien à faire dans /home/pi/Desktop/ (sinon ton bureau va vite devenir le binse), sa place naturelle est dans /usr/local/lib (solution 2 donc).
C'est ce que devrait faire un

Code : Tout sélectionner

make install
d'ailleurs (j'ai pas vérifié avec le GIT que tu donnes ;) )

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

Posté : ven. 10 mars 2017 00:45
par spourre
destroyedlolo a écrit : Donc, plusieurs possibilités :
  1. compiler la version statique la librairie (qui donne un '.a') :
    ...
  2. Placer la librairie dans un répertoire standard comme /usr/local/lib, /usr/local/lib/lib ou /usr/local/lib/lib64 suivant comment to système est configuré (/usr/lib* est réservé aux librairies du système, il est donc déconseillé de le modifier)
  3. Ajouter le répertoire ou se trouve ta librairie dans la variable LD_LIBRARY_PATH genre

    Code : Tout sélectionner

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pi/Desktop/
  4. indiquer le répertoire par l'option -rpath de gcc (très très crade)
Si on veut faire propre, la librairie n'a clairement rien à faire dans /home/pi/Desktop/ (sinon ton bureau va vite devenir le binse), sa place naturelle est dans /usr/local/lib (solution 2 donc).
C'est ce que devrait faire un

Code : Tout sélectionner

make install
d'ailleurs (j'ai pas vérifié avec le GIT que tu donnes ;) )
On a la même analyse sauf que moi, j'ai testé le git et je l'ai compilé en natif, sur mon raspberry, pour être au plus proche de la situation du PO.
Je suis d'accord que mettre la lib dans /usr/lib n'est, peut-être pas, le meiulleur emplacement.
Je l'ai mis là , en cohérence avec d'autres lib qui, elles, disposent d'un make install (libwiringPI par eempel:

Code : Tout sélectionner

pi@raspberry:~/LSM9DS1_RaspberryPi_Library/example $ ll /usr/lib | grep wiringPi
lrwxrwxrwx  1 root root      22 févr. 28 20:07 libwiringPiDev.so -> libwiringPiDev.so.2.40
-rwxr-xr-x  1 root root   28420 févr. 28 13:58 libwiringPiDev.so.2.40
lrwxrwxrwx  1 root root      19 févr. 28 20:07 libwiringPi.so -> libwiringPi.so.2.40
-rwxr-xr-x  1 root root   67768 févr. 28 13:58 libwiringPi.so.2.40

De plus, pour notre ami qui débute, c'est la solution la plus simple, qui ne nécessite que 2 commandes (cp et ldconfig) car on est certain que /usr/lib est dans le PATH.

C'est aussi la solution qui lui permet d'utiliser le Makefile de la bibliothèque, qui prévoit expressément de construire une bibliothèque partagée (option -fPIC et -shared passé au linker):

Code : Tout sélectionner

pi@raspberry:~/LSM9DS1_RaspberryPi_Library $ cat Makefile
CC = g++
LIB = lib/
SRC = src/
INCLUDE = include/

.PHONY: all
all: liblsm9ds1.so

liblsm9ds1.so: $(SRC)LSM9DS1.cpp
        mkdir -p $(LIB)
        $(CC) -I$(INCLUDE) -Wall -O2 -fexceptions $(SRC)LSM9DS1.cpp -lwiringPi -shared -o $(LIB)liblsm9ds1.so

wrapper: $(SRC)
        mkdir -p $(LIB)
        $(CC) -I$(INCLUDE) -Wall -O2 -fPIC -c -lwiringPi $(SRC)LSM9DS1.cpp -o LSM9DS1.o
        $(CC) -I$(INCLUDE) -Wall -O2 -fPIC -c -lwiringPi $(SRC)LSM9DS1_c_wrapper.cpp -o LSM9DS1_c_wrapper.o
        $(CC) -I$(INCLUDE) -Wall -O2 -shared -lwiringPi LSM9DS1.o LSM9DS1_c_wrapper.o -o $(LIB)liblsm9ds1cwrapper.so

clean:
        rm LSM9DS1.o LSM9DS1_c_wrapper.opi@raspberry:~/LSM9DS1_RaspberryPi_Library $
Mon objectif étant de lui permettre d'obtenir assez rapidement un résultat afin de maintenir sa motivation. Je pense qu'il a eu sa dose de théorie et que l'on va le laisser un peu digérer et "bidouiller".
La chaîne de compilation, comme déjà dit, n'est pas une chose facile à comprendre. C'est encore plus vrai avec les outils GNU, sans IDE (on en a déjà parlé).

Sylvain

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

Posté : ven. 10 mars 2017 09:24
par Pinhapple
spourre a écrit :

Code : Tout sélectionner

$ cd ./lib
$ sudo cp  ./*.so  /usr/lib/.
$ cd ../include
$ sudo cp  ./*.h  /usr/include/.
$ sudo  ldconfig
J'ai fait ça comme vous, et ça fonctionne nickel ! ;)
destroyedlolo a écrit :Si on veut faire propre, la librairie n'a clairement rien à faire dans /home/pi/Desktop/ (sinon ton bureau va vite devenir le binse), sa place naturelle est dans /usr/local/lib (solution 2 donc).
La méthode de spourre m'a permis de tout virer du bureau, donc ça va ! J'ai aussi pu enlever l'argument -L/home/pi/... de la commande de compilation :D
spourre a écrit :La chaîne de compilation, comme déjà dit, n'est pas une chose facile à comprendre. C'est encore plus vrai avec les outils GNU, sans IDE (on en a déjà parlé).
Pour mes prochains projets, j'utiliserai un IDE, quitte à développer ailleurs que sur le RPi et à compiler dessus au dernier moment :D

Tout va bien pour le moment du coup, donc merci encore pour votre aide et vos remarques à tous ! :)

Si je me lasse de l'I2C, il y a moyen que je passe à SPI, auquel cas je reposterai ici !

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

Posté : ven. 10 mars 2017 10:20
par spourre
Pinhapple a écrit : ...
J'ai fait ça comme vous, et ça fonctionne nickel ! ;)
....
...
La méthode de spourre m'a permis de tout virer du bureau, donc ça va ! J'ai aussi pu enlever l'argument -L/home/pi/... de la commande de compilation :D
...
Pour mes prochains projets, j'utiliserai un IDE, quitte à développer ailleurs que sur le RPi et à compiler dessus au dernier moment :D

Tout va bien pour le moment du coup, donc merci encore pour votre aide et vos remarques à tous ! :)

Si je me lasse de l'I2C, il y a moyen que je passe à SPI, auquel cas je reposterai ici !
Bonjour Pinhapple,

Je suis bien content que cela fonctionne aussi chez vous, mais je n'avais pas beaucoup de doutes sur le résultat puisque j'avais testé sur pi.
Maintenant, vous allez pouvoir explorer un peu votre gyro et voire si le C + libwiringPi + i2c vous permettent d'atteindre votre objectif.
après, il sera temps de passer au SPI.

Maintenant que "ma recette" fonctionne, il faut essayer de comprendre le pourquoi et le comment. C'est primordial avant de passer à un IDE qui, in fine, vous posera les mêmes questions (emplacement des includes, des bibliothèques, options du compilateur, du linker...)
Essayez de relire, à tête reposée, l'ensemble des contributions. Elles apportent toutes une information et se complètent assez bien.

Si vous considérez avoir reçu la réponse à votre question initiale (lecture LSM9DS1 en I2C), vous pouvez passer le topic en résolu pour faciliter la lecture du forum.

Cordialement

Sylvain

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

Posté : ven. 10 mars 2017 10:30
par destroyedlolo
Lorsque quelqu'un vient demander des renseignements, j'essaie (et ne réussi pas toujours) de répondre à sa demande et lui laissant le choix des alternatives en expliquant les pours et les contres plutot que lui donner une solution simpliste sans lui expliquer les impactes.
Dans le cas présent, le PO faisant des compiles locale, en utilisant les chaines GNU et sans je crois de connexion réseau sur cette machine, il me parait beaucoup pertinent de lui expliquer comment garder un système propre que de diverger vers de la cross compile qu'il ne pourra pas de toutes façons utiliser (d'autant plus qu'il y a vraiment plus simple que d'utiliser une VM pour ca). Parce que, mélanger de manière anarchique les lib packagées avec celles compilées n'amène tot ou tard qu'a une seule chose : la réinstallation du système. Autant donc prendre les bonnes habitudes des le début.
spourre a écrit :La chaîne de compilation, comme déjà dit, n'est pas une chose facile à comprendre. C'est encore plus vrai avec les outils GNU, sans IDE (on en a déjà parlé).
Tant qu'on reste sur un petit projet, ce qui est le cas ici, la chaine de compilation est on ne peut plus simple, gnu ou pas gnu :
  • gcc
  • fichiers sources
  • librairie
  • destination
D'autant plus que le PO a déjà fait les premiers pas. Rien de transcendant et surtout utile pour le jour où l'on doit installer qq chose à la main ... ce qui est aussi le cas ici.
Les autres options (surtout niveau optimisation et cibles) sont nombreuses et complexes, là on est bien d'accord ... mais pas obligatoire : il y viendra si nécessaire par la suite.

Quand aux IDE, sujet sur lequel je me suis bien abstenu d'intervenir, je suis bien évidement opposé à l'assertion comme quoi les lignes de commandes sont d'un autre temps surtout quant à préconiser l'usage d'une IDE obèse et de plus n'a rien à voir avec ce qu'on a sous Nunux, avec de la remote compile et je ne sais quoi. La majorité des gros Dev sous Unix se font en IDE, c'est clair (mais certainement pas VC), mais 99.99% des compilations finales ont lieu avec des Makefile ... simplement parce que c'est la seule et unique méthode vraiment portable. Et s'il est bien évident que peu de monde s'amuse à faire les makefile à la main (y'a des outils pour ça) ... la compréhension de la chaine puis des Makefile est un prérequis important lorsqu'on commence à avoir une utilisation qui sort des packages tout fait.
Ca n'empeche évidement en rien l'utilisation d'une IDE, qui facile bien la vie ... une fois qu'on l'a apprivoisé, mais sur les projets finaux, elle est complementaire de la ligne de commande.

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

Posté : ven. 10 mars 2017 11:12
par Pinhapple
spourre a écrit :Maintenant, vous allez pouvoir explorer un peu votre gyro et voire si le C + libwiringPi + i2c vous permettent d'atteindre votre objectif.
après, il sera temps de passer au SPI.
J'obtiens de meilleurs résultats traités en C, que bruts en Python, donc je m'approche de mon objectif ! :)
Je pense toutefois être limité à la fois par I2C comme Bud Spencer l'a montré, et par la biblio lsm9ds1 téléchargé et installée avec peine : cette biblio propose des résultats traités, n'a pas de fonction pour récupérer l'orientation (seulement la vitesse angulaire), et ne propose pas l'utilisation de SPI ; donc plutôt que d'adapter la bibliothèque, autant recommencer de zéro à la main en C et SPI ! Après tout, je n'ai "plus qu'à" lire les valeurs brutes du LSM9DS1 avec WiringPi, et que je sais désormais les convertir :D
spourre a écrit :Maintenant que "ma recette" fonctionne, il faut essayer de comprendre le pourquoi et le comment. C'est primordial avant de passer à un IDE qui, in fine, vous posera les mêmes questions (emplacement des includes, des bibliothèques, options du compilateur, du linker...)
Essayez de relire, à tête reposée, l'ensemble des contributions. Elles apportent toutes une information et se complètent assez bien.
Je commence déjà à y voir plus clair, et à comprendre à quoi correspondent les #include du C !
spourre a écrit :Si vous considérez avoir reçu la réponse à votre question initiale (lecture LSM9DS1 en I2C), vous pouvez passer le topic en résolu pour faciliter la lecture du forum.
Je vais faire ça ;)
Par contre, si j'ai besoin d'aide en SPI, j'imagine que j'ouvre un nouveau topic ?
destroyedlolo a écrit :Lorsque quelqu'un vient demander des renseignements, j'essaie (et ne réussi pas toujours) de répondre à sa demande et lui laissant le choix des alternatives en expliquant les pours et les contres plutot que lui donner une solution simpliste sans lui expliquer les impactes.
Les possibilités proposées étaient très claires ;)
destroyedlolo a écrit :Dans le cas présent, le PO faisant des compiles locale, en utilisant les chaines GNU et sans je crois de connexion réseau sur cette machine, il me parait beaucoup pertinent de lui expliquer comment garder un système propre que de diverger vers de la cross compile qu'il ne pourra pas de toutes façons utiliser (d'autant plus qu'il y a vraiment plus simple que d'utiliser une VM pour ca). Parce que, mélanger de manière anarchique les lib packagées avec celles compilées n'amène tot ou tard qu'a une seule chose : la réinstallation du système. Autant donc prendre les bonnes habitudes des le début.
Comme dit plus haut, je m'y retrouve mieux dans l'organisation des fichiers et leur emplacement, et je comprends petit à petit comment tout s'articule :)
J'ai déjà fait du C avec Code::Blocks, et c'est tout aussi intéressant de comprendre comment ça marche que de coder !

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

Posté : ven. 10 mars 2017 15:27
par Pinhapple
Je n'ai pas l'impression que le LSM9DS1 soit accessible en SPI depuis le RPi... :?

Vraiment par curiosité et histoire d'en être définitivement débarrassé : indépendamment du langage de programmation utilisé, si je souhaite récupérer les valeurs brutes de rotation et d'accélération sur les trois axes (donc au total les valeurs brutes de vitesse angulaire pour les axes X, Y, et Z et les valeurs d'accélération pour les axes X, Y, et Z), combien pourrais-je au maximum et en théorie en récupérer par seconde ?

La bibliothèque dont j'ai parlé précédemment me permet d'obtenir ces valeurs traitées (donc perte de temps dans la boucle le temps de traiter les valeurs brutes) en 28 secondes pour 10 000 itérations, soit environ 357 (* 6) valeurs/seconde.

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

Posté : dim. 12 mars 2017 13:05
par spourre
Pinhapple a écrit :Je n'ai pas l'impression que le LSM9DS1 soit accessible en SPI depuis le RPi... :?

Vraiment par curiosité et histoire d'en être définitivement débarrassé : indépendamment du langage de programmation utilisé, si je souhaite récupérer les valeurs brutes de rotation et d'accélération sur les trois axes (donc au total les valeurs brutes de vitesse angulaire pour les axes X, Y, et Z et les valeurs d'accélération pour les axes X, Y, et Z), combien pourrais-je au maximum et en théorie en récupérer par seconde ?

La bibliothèque dont j'ai parlé précédemment me permet d'obtenir ces valeurs traitées (donc perte de temps dans la boucle le temps de traiter les valeurs brutes) en 28 secondes pour 10 000 itérations, soit environ 357 (* 6) valeurs/seconde.
La théorie peut permettre une estimation, à la louche (une grosse louche).
Si on fait la synthèse de ce qui a déjà été répondu, on note:

1) que le gyro accepte l' I2C "rapide" (mais l'I2C reste un bus lent).
2) que le lsm9ds1 peut être mis en mode non bufférisé (cf. data sheet).

En admettant, dans un premier temps, un temps de traitement nul (ça n’existe pas) et en connaissant la taille des échantillons, on arrive à un nombre de lecture max = débit I2C / (taille échantillon x nombre échantillon).
Ne pas oublier:
l'I2C et le LSM imposent des délais.
le programme et sa bibliothèque sont en "user land" donc soumis à la charge du CPU, au swapp du scheduler ...

Les pistes:

1) décortiquer la bibliothèque pour, éventuellement, mettre en commentaire la partie "décodage" et incrémenter un compteur. puis recompiler. en programme "normal"

2) Comme déjà écrit, aller au plus proche du matériel en prenant des bibliothèque de niveau d'abstraction moindre:

- ) la libwiringPi
-) la bcm (qui est une statique )
-) tout faire à la main avec les périphériques du SOC

Coté programme, les pistes d’optimisation sont:
- utiliser des variables entières, en registre si possible.
- utiliser les opérateurs bit à bit (décalage, masque..)

3) limiter la charge du CPU en virant tous les services initiles (cups ? wifi .., logs ...)

Mais, j'insiste, Linux n'est pas (et ne prétend pas être) temps réeel. Soit votre application (robot ? drone ..) peut tolérer la perte de mesures (en interpollant par exemple), soit il faut passer aux extensions RT du kernel.

Sylvain

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

Posté : dim. 12 mars 2017 13:52
par guillaume9344
Mais au fait, pourquoi avoir besoin d autant d échantillons par secondes ?