IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Utiliser python ?


Sujet :

Arduino

  1. #21
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 933
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 933
    Par défaut
    Citation Envoyé par Delias Voir le message
    Ouai bon je n'ai pas voulu réagir, mais c'est n'importe quoi. Comment un langage incapable de fonctionner sur plus de 50% des modèles de puces concernées peut être classé premier? Ou alors l'embarqué ce n'est plus que les micro-ordi avec OS et je passe pour un dinosaure?
    Tout à fait d’accord, s’il faut l’utiliser de manière avancée en physique / au travers de plusieurs matières, c’est une décision dénuée de sens. Il serait bon de Clarifier l’objectif, définir les acquis que l’on souhaite obtenir et ensuite regarder les solutions possibles.


    Sur Arduino Uno, il est possible de faire de l'ASM (spécifique AVR), C et C++. On évitera pour autant de faire de la gestion mémoire dynamique (toutes les variables sont définie dans le code et reçoive une adresse par le compilateur, pas de malloc, free, etc.) et du polymorphisme (méthode virtuelle) car bien que admit par le compilateur il n'y a pas les protections de dépassement (pour la mémoire) et cela plombe les perfs.
    Arduino c’est à la fois la carte et l’IDE. Il n’y a pas de «*langage*» arduino. L’IDE a choisi la programmation en C++ , c’est LE C++ standard avec un compilateur standard (bien sûr avec les contraintes matérielles, pas d’OS embarqué, peu de mémoire, pas de clavier, écran en standard etc)

    L’environnement de développement offre des bibliothèques de fonctions et de classes (les fameuses ‘Libraries’). Je suis d’accord sur la recommendation d'être Plutôt en mémoire RAM statique car il y en a peu, mais bien géré le malloc() reste envisageable (plus sur ESP) même si déconseillé en général sur petit micro-contrôleur.

    La notion de hiérarchie de classe cependant / polymorphisme etc n’apporte aucune réelle contrainte pour la majorité des applications et rend le code et sa maintenance plus simple, au final c’est entièrement compilé. Effectivement dans le cadre du run-time polymorphisme le compilateur rajoute du code pour identifier le pointeur sur la bonne fonction, c’est une indirection relativement courte pour trouver quelle fonction choisir, et ça ne plombe pas trop les performances pour l’essentiel des usages (qui se contente le plus souvent de juste la surcharge de fonctions ou opérateurs)

    Il faut l’utiliser à bon escient, comme tout bon outil mais se passer des vertus de la programmation orientée objet et ses concepts associés c’est rater une opportunité de réflexion sur la bonne structuration d’un code et sa maintenabilité (et ça permet de comprendre ensuite les librairies et leur usage)

    Un souci commun que je vois dans l’usage du python c’est le niveau d’abstraction très élevé fait que les apprenants ne comprennent pas ce qu’il se passe en dessous au niveau mémoire et performance. de même on voit tous les jeunes (et moins jeunes) utiliser abondamment la classe String sur petit arduino alors que c’est un risque pour le morcellement mémoire (allocation dynamique, pas de ramasse miettes), les performances et la taille du programme... le C ou C++ est bcp plus adapté à ces architectures embarquées, c’est tout...

    Pour des débutants c'est soit ASM soit C/C++, mais inutile de vouloir les mélanger. De plus on peut accéder à 100% des fonctionnalité de la puce en C/C++, inutile de faire de l'ASM sauf à vouloir gratter des pour mille de performance.
    oui la phase d’optimisation du compilateur fait que bien souvent le code généré sur base de C++ sera plus performant que du code assembleur écrit à la main.


    Par contre faire en C ou en C++ au lieu de Arduino c'est minima 25% de perfs en plus.
    Je pense que ce genre de phrase à l'emporte Pièce ne veut rien dire. Comme vous l’avez expliqué Arduino ce n’est pas un langage de programmation, donc vous mélangez les serviettes et les torchons. On fait du C++ même quand in appelle les fonctions et Libraries fournies dans le cadre de l’environnement de développement (IDE). Les auteurs de ces fonctions ayant voulu faire «*portable*» et «*ceinture bretelle*» , c’est clair que l’efficacité comparée à titiller en direct un registre n’est pas au rendez vous. En échange l’apprenant n’a qu’à se souvenir de digitalRead() ou digitalWrite() et ça fonctionnera sur ATMEGA, ESP,... sans avoir à se plonger dans la doc de référence de l’architecture du micro-processeur;

    Vous voulez faire de l'embarqué, alors faîtes de l'embarqué dans son langage. Arduino reste simple à comprendre.

    La solution python c'est plus du genre "acquisition de signal" et là LabView c'est 1'000'000 fois mieux. Tout le traitement du signal peut être fait rapidement sans pour autant mettre les mains dans le cambouis. Et à mon avis la solution Python est plus compliquée et plus décourageante que l'Arduino ou LabView. (Mais LabView ce n'est pas pour la 1ère prépra, c'est pour plus tard).
    1000% d’accord. On devrait apprendre à l’école à utiliser le bon outil au bon moment, dans le cadre d’une démarche scientifique d’analyse du besoin... sinon on tombe dans l’aphorisme appelé “Marteau de Maslow”:
    « Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou »
    Abraham Maslow (The Psychology of Science, 1966).


    Cette tentation qui consiste à travestir la réalité d’un problème en le transformant en fonction des réponses dont on dispose, ou encore le fait de considérer qu’il n’y a qu’une réponse unique à tous les problèmes est une hérésie scientifique....

    Il faut vite tuer cette idée pour le bien des futures générations et la santé mentale de nos profs de physique et maths...



    EDIT: je voulais en avoir le coeur net sur le coût du "runtime polymorphism" pour les fonctions virtuelles, où le compilateur doit décider lors de l'exécution quelle fonction appeler. j'ai donc écrit ce petit bout de code, avec une classe et sous classe utilisant une fonction membre virtuelle et un tableau d'éléments du type de la classe de base mais contenant un exemplaire d'instance de la classe de base et un autre de la classe dérivée.
    puis j'ai écrit une autre hiérarchie avec juste de la surcharge de fonction membre.
    le code mesure (à la louche et aux interruptions près) en micro-seconde le temps d'exécution de l'appel (sachant que j'ai moins de 64 caractères dans le buffer série, donc la fonction print ne sera pas bloquante);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    class ClasseDeBaseVirtual
    {
      public:
        virtual void coucou() {
          Serial.println(F("Coucou de base   "));
        }
    };
     
    class ClasseDeriveeVirtual: public ClasseDeBaseVirtual
    {
      public:
        void coucou() {
          Serial.println(F("Coucou de Derivee"));
        }
    };
     
    class ClasseDeBase
    {
      public:
        void hello() {
          Serial.println(F("Hello de base      "));
        }
    };
     
    class SousClasse: public ClasseDeBase
    {
      public:
        void hello() {
          Serial.println(F("Hello de SousClasse"));
        }
    };
     
     
    ClasseDeBaseVirtual* liste[] = {new ClasseDeBaseVirtual, new ClasseDeriveeVirtual}; 
     
    ClasseDeBase b;
    SousClasse s;
     
    void setup() 
    {
      Serial.begin(115200);
      unsigned long chrono;
      volatile size_t index;// pour éviter les optimisations du compilateur
     
      Serial.println(F("----- RESOLUTION DYNAMIQUE AU RUNTIME -----"));
      index = 0;
      chrono = micros();
      liste[index]->coucou();
      Serial.println(micros() - chrono);
      delay(1000); // pour ne pas être impacté par les interruption du Serial.print
     
      index = 1;
      chrono = micros();
      liste[index]->coucou();
      Serial.println(micros() - chrono);
     
      Serial.println(F("----- RESOLUTION STATIQUE A LA COMPILATION -----"));
      delay(1000); // pour ne pas être impacté par les interruption du Serial.print
     
      chrono = micros();
      b.hello();
      Serial.println(micros() - chrono);
     
      delay(1000); // pour ne pas être impacté par les interruption du Serial.print
      chrono = micros();
      s.hello();
      Serial.println(micros() - chrono);
    }
     
    void loop() {}
    si vous exécutez ce bout de code sur un UNO, on voit dans le moniteur série (à 115200 bauds)

    ----- RESOLUTION DYNAMIQUE AU RUNTIME -----
    Coucou de base
    148
    Coucou de Derivee
    136
    ----- RESOLUTION STATIQUE A LA COMPILATION -----
    Hello de base
    148
    Hello de SousClasse
    148
    On voit donc que la résolution dynamique apporte une petite variation (136μs versus 148μs entre les 2 appels) alors que le temps est constant pour la partie statique ) 148μs

    -> Sachant en plus que la résolution de la fonction micros() est de 4 μs on ne peut pas dire que le prix à payer soit exorbitant - les valeurs sont "comparables" en premier abord et à notez qu'on a en plus le prix d'un appel à micros() et le temps d'une soustraction sur un unsigned long en plus dans le temps calculé.. donc on n'est pas super précis..

    Si on veut aller plus loin on pourrait basculer la valeur d'une pin avant et après l'appel de fonction et mesurer à l'oscilloscope (en déclenchant sur front montant) la durée de l'appel de fonction.

    voici un nouveau code à peu près similaire mais dans lequel
    - J'ai réduit la taille de ce qu'on imprime (ça génère des interruptions qu'on ne veut pas)
    - J'ai augmenté le débit en baud pour minimiser les temps à attendre.
    - J'ai viré le timing par calcul sur le nombre de microsecondes
    - J'utilise le registre PINB (ça prend 1 cycle donc 62.5ns) pour basculer la pin 8

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    class ClasseDeBaseVirtual
    {
      public:
        virtual void coucou() {
          Serial.write('1');
        }
    };
     
    class ClasseDeriveeVirtual: public ClasseDeBaseVirtual
    {
      public:
        void coucou() {
          Serial.write('2');
        }
    };
     
    class ClasseDeBase
    {
      public:
        void hello() {
          Serial.write('3');
        }
    };
     
    class SousClasse: public ClasseDeBase
    {
      public:
        void hello() {
          Serial.write('4');
        }
    };
     
     
    ClasseDeBaseVirtual* liste[] = {new ClasseDeBaseVirtual, new ClasseDeriveeVirtual};
     
    ClasseDeBase b;
    SousClasse s;
     
    void setup()
    {
      Serial.begin(1000000);
      pinMode(8, OUTPUT); // le pin 8 est sur le port B de mon UNO, sur le bit de poid faible
      digitalWrite(8, LOW); // on met la pin 8 au repos
     
      delay(1000);
     
      volatile size_t index;// pour éviter les optimisations du compilateur
     
      index = 0;
      PINB = 0b00000001; // on active (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      liste[index]->coucou();
      PINB = 0b00000001; // on désactive (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      delayMicroseconds(10); // pour ne pas être impacté par les interruption du Serial.write
     
      index = 1;
      PINB = 0b00000001; // on active (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      liste[index]->coucou();
      PINB = 0b00000001; // on désactive (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      delayMicroseconds(10); // pour ne pas être impacté par les interruption du Serial.write
     
      PINB = 0b00000001; // on active (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      b.hello();
      PINB = 0b00000001; // on désactive (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      delayMicroseconds(10); // pour ne pas être impacté par les interruption du Serial.write
     
      PINB = 0b00000001; // on active (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
      s.hello();
      PINB = 0b00000001; // on désactive (bascule) la pin 8. cette instruction est 1 cycle d'horloge soit 62.5ns sur un UNO à 16Mhz
    }
     
    void loop() {}
    Voilà à quoi la capture écran de l'oscilloscope ressemble:
    Nom : tempo.png
Affichages : 198
Taille : 1,77 Mo

    On peut voir que le temps d'exécution de notre fonction avec résolution du pointeur de fonction au runtime est de l'ordre de réellement de 7μs (incomparable avec les 148μs ci dessus car pas le même texte ni usage de la macro F()) alors que le temps d'exécution de notre fonction au contenu similaire en résolution à la compilation est de l'ordre de 5.5μs. Pour être exact il faudrait enlever le temps d'indirection puisque je vais chercher les instances dans un tableau mais Il y a donc effectivement un impact de performance en pourcentage de l'ordre de 15% à 25% je pense - ce qui est beaucoup en absolu si on est pressé, mais en pratique on ne parle que de 1 à 1.5 micro-seconde d'écart, ce qui conviendra à une très grande majorité.

    Bien sûr si on avait une hiérarchie de classes plus profonde ce serait un peu plus pénalisant, mais la majorité des cas que j'ai vu ne dépassent pas ce genre de construction à 1 étage et si c'est un truc au coeur d'une boucle critique ou chaque microseconde compte, alors on évitera effectivement les fonctions membres virtuelles

    et.... c'est trop avancé de toutes façons pour des débutants

  2. #22
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Citation Envoyé par Delias Voir le message
    Secondaire, c'est l'avant-dernière année avant le bac?
    C'est ça et en France on veut même commencer à familiariser les étudiants à l'informatique à l'avant-avant dernière année avant le bac.

    L'idée n'est absolument pas de faire de l'embarqué car il y a des spécialités pour ça et elles viennent plus tard sachant aussi que les étudiants ont la liberté de se réorienter après. Et entre nous, si le prof de Math doit en plus de son programme classique, doit aussi faire tout un programme d'informatique il est clairement mal. Pareil pour le prof de Physique.

    La langage informatique doit permettre d'explorer les mathématiques différemment (comment je modélise un problème, comment je raisonne de manière logique, comment je visualise une distribution....) et pour la Physique, en choisissant un RTU assez simple, on peut donner encore plus de vie à cette science (TP plus vivant, comment j'applique ce que j'ai vu en math sur un problème très réel, comment mettre en oeuvre une convolution avec des vraies signaux pour donner encore plus de sens à ce que j'ai appris en math, ...)

    L'étudiant doit voir le langage informatique comme une aide et un outil pour la suite de son parcours scolaire, quel qu'il soit. Mais il ne faut pas en faire un informaticien ni un spécialiste de l'embarqué.

    Pour moi l'idée d'avoir choisie Python est bonne.
    Le langage est assez facile à prendre en main et ne nécessite pas d'avoir des prérequis "spécialisés". Si on avait choisi le C ou le C++ ça démarrait mal car il le langage est typé (un char c'est 8 bit, un short c'est 16 bits etc...) et il faudrait commencer par aborder des notions d'électronique. En fait le niveau d'abstraction de Python est parfait pour se servir du langage comme "compagnon" de la discipline car c'est ça l'idée.


    Citation Envoyé par Delias Voir le message
    La solution python c'est plus du genre "acquisition de signal" et là LabView c'est 1'000'000 fois mieux. Tout le traitement du signal peut être fait rapidement sans pour autant mettre les mains dans le cambouis. Et à mon avis la solution Python est plus compliquée et plus décourageante que l'Arduino ou LabView. (Mais LabView ce n'est pas pour la 1ère prépra, c'est pour plus tard).
    Oui je suis d'accord, LabView, Scilab, Matlab aurait été des candidats parfaits quoi que tous sont un peu trop orientés système embarqué. L'étudiant qui continue dans le domaine des maths ne va pas être aidé avec Labview, c'est plutôt Scilab ou Matlab.

    Citation Envoyé par Jay M Voir le message
    On devrait apprendre à l’école à utiliser le bon outil au bon moment, dans le cadre d’une démarche scientifique d’analyse du besoin... sinon on tombe dans l’aphorisme appelé “Marteau de Maslow”:
    « Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou »
    Abraham Maslow (The Psychology of Science, 1966).


    Cette tentation qui consiste à travestir la réalité d’un problème en le transformant en fonction des réponses dont on dispose, ou encore le fait de considérer qu’il n’y a qu’une réponse unique à tous les problèmes est une hérésie scientifique....

    Il faut vite tuer cette idée pour le bien des futures générations et la santé mentale de nos profs de physique et maths...
    Oui il faut faire très attention à ça

  3. #23
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 933
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 933
    Par défaut
    Citation Envoyé par Vincent PETIT Voir le message
    Pour moi l'idée d'avoir choisie Python est bonne.
    Le langage est assez facile à prendre en main et ne nécessite pas d'avoir des prérequis "spécialisés". Si on avait choisi le C ou le C++ ça démarrait mal car il le langage est typé (un char c'est 8 bit, un short c'est 16 bits etc...) et il faudrait commencer par aborder des notions d'électronique. En fait le niveau d'abstraction de Python est parfait pour se servir du langage comme "compagnon" de la discipline car c'est ça l'idée.
    On est d'accord, mais il faut dans ce cas se cantonner au mac/pc et pas essayer d'appliquer cela à un arduino... on confond tout ensuite..

    et sinon, introduire le code beaucoup plus tôt dans le cursus (à partir du primaire) serait une bonne idée à mon avis... comme ça arrivé en 1ère ou terminale, il y aurait un acquis plus important (et on aurait peut-être ainsi plus de vocations pour le métier d'ingénieur en informatique / électronique ... on en manque cruellement).

  4. #24
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Citation Envoyé par Jay M Voir le message
    On est d'accord, mais il faut dans ce cas se cantonner au mac/pc et pas essayer d'appliquer cela à un arduino... on confond tout ensuite.
    Mon avis là dessus c'est que si Arduino il y a, par exemple pour la physique à l'aide de Python, il faut qu'il ne serve qu'a acquérir une tension avec un pas d'échantillonnage - peut être avec la possibilité de choisir la Vref interne - et que personne ne le programme ni même le voit (il est juste une centrale d'acquisition) et comme tu le dis, afin que le travaille d'initiation à l'algo et au Python ne se fasse que sur un PC.

    Citation Envoyé par Jay M Voir le message
    et sinon, introduire le code beaucoup plus tôt dans le cursus (à partir du primaire) serait une bonne idée à mon avis... comme ça arrivé en 1ère ou terminale, il y aurait un acquis plus important (et on aurait peut-être ainsi plus de vocations pour le métier d'ingénieur en informatique / électronique ... on en manque cruellement).
    100% d'accord


    - Réflexion très personnelle -
    Pour ce que tu écrivais avec le Marteau de Maslow, je crois (et j'en suis intimement persuadé) que Arduino à l'école c'est très casse gueule même si il a été développé dans un but pédagogique. Il y a un trop grand risque d'illusion :
    de faire de l'électronique alors que principalement on connecte des cartes électroniques
    de concevoir des projets très aboutis sans rien avoir réellement choisie ou dimensionné
    de produire des logiciels pointus à l'aide de copier/coller

    Le risque d'illusion est d'autant plus fort que les chances de réussite sont quasiment de 100% même en tombant dans les 3 pièges que je viens de noter. Arduino pourrait être perçu comme une solution a tous les problèmes dans les systèmes embarqués.

    Ça me fait penser à STM32CubeMx qui permet de configurer visuellement les registres des micro ARM de chez STM32. Cet outil fait gagner un temps de fou et en plus il génère une couche d'abstraction matérielle qui permet finalement de s'affranchir du microcontrôleur. Mais si tu mets ça à l'école, tu créais des promotions complètes d'étudiants qui se retrouveront en grande difficulté face à d'autres microcontrôleurs. Quand ça fait gagner trop de temps et que c'est trop simple, il faut se méfier (surtout si c'est pour de l'apprentissage... lorsqu'on est du métier par contre là je reconnais que ça aide).

  5. #25
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Je continue de lire les liens que vous m'avez indiqué...
    Encore merci.

    Je vais ouvrir d'autres fils car du coup je me pose d'autres questions...

Discussions similaires

  1. Problèmes pour utiliser Python.h
    Par micheldup dans le forum Interfaçage autre langage
    Réponses: 7
    Dernier message: 29/09/2008, 18h08
  2. utiliser python pour utiliser XSLT
    Par DrDam dans le forum Général Python
    Réponses: 1
    Dernier message: 25/05/2008, 16h26
  3. Utiliser python comme PHP.
    Par iflypunk dans le forum Réseau/Web
    Réponses: 5
    Dernier message: 19/12/2007, 13h21
  4. Comment utiliser Python avec un RAD
    Par marjal dans le forum EDI/RAD
    Réponses: 3
    Dernier message: 10/03/2007, 19h07
  5. Utiliser Python et PostGresql pour créer un site Web
    Par rvweb dans le forum Réseau/Web
    Réponses: 8
    Dernier message: 22/10/2006, 20h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo