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 :

Projet : Recherche de bonne connectique


Sujet :

Arduino

  1. #21
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Salut Jay M

    Tu as certainement raison, ton explication sort un peu de la capacité de compréhension de mes vieux neurones!
    J'ai fait un essai avec un UNO et un tableau de 200 cela prend moins de 350 millisecondes.
    Avec un tableau de 4, ^4 millisecondes et cela s'exécute qu'une fois.

    Cordialement
    jpbbricole
    avec 200 ? vous avez conservé le randomSeed() dans la boucle while (celui de la ligne 17 dans le code que j'ai copié dans ma réponse) ?

    Sinon je ne dis pas que ça ne marche pas dans votre cas avec N tout petit, juste que ça va prendre un certain temps (comme le fût du canon) qui est indéterminée et que plus N est grand, plus c'est difficile et ça va prendre du temps voire ne jamais marcher.

    Explication:

    En gros au début vous avez les N cases de votre tableau rndTest toutes à false. (donc 0 à true)
    Imaginons que N = 1000

    vous tirez un nombre au hasard, vous êtes sûr de tomber sur une case 'false' puisqu'il n'y en a pas de 'true'

    Vous avez donc maintenant 999 cases à 'false' et 1 à 'true'

    Vous tirez un nombre au hasard, si vous n'avez pas de bol vous pouvez tomber sur la case qui est déjà 'true' et vous devez faire un nouveau tirage. la probabilité que vous tombiez sur une case 'true' c'est 1 / 1000 puisque vous n'avez qu'une case 'true' sur les 1000 -> 0.1% de chances de tomber sur un 'true', vous allez donc très vite trouver une case 'false'

    Une fois cette seconde case cochée, Vous avez donc maintenant 998 cases à 'false' et 2 à 'true'
    même chose, mais ce coup ci vous avez (2 / 1000) chances de tomber sur une case déjà à 'true' -> 0.2% de chances de tomber sur un 'true'

    ainsi de suite.

    Quand vous aurez cochées déjà 500 cases vous aurez 500 / 1000 = 50% de chances de tomber sur case occupée --> il vous faudra quelques tirages sans doute pour trouver une case 'false'

    quand vous aurez 900 cases cochées, vous aurez 900 / 1000 = 90% de chances de tomber sur case occupée --> il vous faudra de nombreux tirages sans doute pour trouver une case 'false'

    quand vous aurez 990 cases cochées, vous aurez 990 / 1000 = 99% de chances de tomber sur case occupée --> il vous faudra de nombreux tirages sans doute pour trouver une case 'false'

    quand vous arrivez à la dernière, vous aurez 999 cases cochées, vous aurez 999 / 1000 => juste 0,1% de chances de tomber sur la bonne case encore libre --> il vous faudra de très nombreux tirages sans doute pour trouver cette case 'false'

    --> en gros, plus vous cochez les cases, plus c'est difficile de tomber par hasard sur une case libre.

    Ce que vous pouvez faire c'est modifier votre code de test pour compter le nombre d'essais nécessaires pour finir le mélange

    voilà un bout de code à tester
    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
    size_t filsNombre = 100;
    boolean rndTest[1000];     // Pour tester sur la valeur est déjà tirée
     
     
    unsigned long entreesPinMelange()
    {
      size_t rndNumber;
      size_t rndIndex = 0;
     
      unsigned long nombreDessais = 0;
     
      for (size_t r = 0; r < filsNombre; r++)                       // Tout le tableau de test à false
      {
        rndTest[r] = false;
      }
     
      while (rndIndex < filsNombre)
      {
        // randomSeed(analogRead(0));                              // ATTENTION SI ON FAIT CA ON AUGMENTE LE RISQUE DE TOURNER SANS FIN
        rndNumber = random(0, filsNombre);
        nombreDessais++;
     
        if ((nombreDessais % 500UL) == 0) Serial.write('.'); // on met un point tous les 500 tests
     
        if (rndTest[rndNumber] == false)                        // Si nombre hasard pas déjà tiré
        {
          // entreesPin[rndIndex] = entreesPinBase[rndNumber];   on ne le fait pas pour économiser la mémoire
          rndTest[rndNumber] = true;                          // Enregistrer le numéro comme tiré
          rndIndex ++;
        }
      }
      //  Serial.print("il a fallu ");
      //  Serial.print(nombreDessais);
      //  Serial.println(" essais ");
      return nombreDessais;
    }
     
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));
    }
     
    void loop() {
      unsigned long minEssai = 0xFFFFFFFF, maxEssai = 0;
     
      // on mélange 20 fois pour voir le min et max du nombre d'essais
      for (int i = 0; i < 20; i++) {
        unsigned long n = entreesPinMelange();
        if (n > maxEssai) maxEssai = n;
        if (n < minEssai) minEssai = n;
      }
     
      Serial.print("\nil a fallu entre ");
      Serial.print(minEssai);
      Serial.print(" et ");
      Serial.print(maxEssai);
      Serial.print(" essais pour N=");
      Serial.println(filsNombre);
     
      filsNombre += 100;
      if (filsNombre > 1000) while (true); // on ne va pas plus loin le tableau déborderai
    }
    je reprends votre algo, j'ai viré les 2 tableaux car pas la peine d'occuper trop de mémoire et j'ai mis le tableau vrai/faux en global avec une taille max

    j'ai aussi viré la régénération des nombres aléatoire en cours de boucle (le randomSeed) sinon ça ne converge pas car pour une seed donnée vous êtes à peu près sur de tomber sur votre chiffre dans un délai raisonnable mais si vous changez la seed à chaque fois, on augmente le risque.

    voilà ce que ça me donne:



    ................
    il a fallu entre 360 et 1115 essais pour N=100
    ..........................................
    il a fallu entre 924 et 2251 essais pour N=200
    ...................................................................
    il a fallu entre 1337 et 2469 essais pour N=300
    ................................................................................................
    il a fallu entre 2145 et 4259 essais pour N=400
    ..................................................................................................................................
    il a fallu entre 2286 et 6533 essais pour N=500
    ....................................................................................................................................................
    il a fallu entre 3242 et 4938 essais pour N=600
    ........................................................................................................................................................................................................
    il a fallu entre 3647 et 7281 essais pour N=700
    .................................................................................................................................................................................................................................
    il a fallu entre 4612 et 9303 essais pour N=800
    .................................................................................................................................................................................................................................................................
    il a fallu entre 4666 et 10728 essais pour N=900
    ...................................................................................................................................................................................................................................................................................................
    il a fallu entre 5670 et 9908 essais pour N=1000


    si on met le randomSeed() et que j'avance de 5 en 5


    il a fallu entre 5 et 24 essais pour N=5

    il a fallu entre 11 et 40 essais pour N=10

    il a fallu entre 28 et 82 essais pour N=15

    il a fallu entre 38 et 84 essais pour N=20
    ..................................................
    il a fallu entre 127 et 5851 essais pour N=25
    ... // .....
    il a fallu entre 1043 et 115608 essais pour N=30


    --> et ça bloque (enfin ça prend tellement longtemps que j'ai arrêté d'attendre)


    Dans le cas de l'algo que j'ai posté on fait (N-1) opérations à tous les coups pour mélanger le tableau de N éléments. donc même avec 1000 éléments dans le tableau on ne fera que 999 tirages aléatoires et échanges.

  2. #22
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    Hello, je suis paumé.

    Vos codes plantent et je n'arrive pas à y remédier avec mes compétences limitées.

    le code avec les tests de JayM fonctionne, mais celui avec les permutations et ceux de jpbbricole, non.

    HELP ME

    C'est balo, je comprends vos raisonnements.
    Ce que je ne comprends pas aussi, c'est pourquoi la randomisation des sorties est codée à la fin?

  3. #23
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    vous prenez cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void melange()
    {
      // algo cf https://fr.wikipedia.org/wiki/Mélange_de_Fisher-Yates
      for (size_t i = nombreDeDonnees - 1; i >= 1; --i) {
        size_t j = random(0, i + 1);
        donnee_t echange = maListe[i];
        maListe[i] = maListe[j];
        maListe[j] = echange;
      }
    }
    et vous remplacez
    - nombreDeDonnees par votre variable qui contient le nombre de données
    - donnee_t par le type des données dans votre tableau
    - maListe[] par votre tableau

    ça va mélanger votre tableau

  4. #24
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    Autant pour moi,
    Dans le simulateur tinkercad, votre code plante et ça fonctionne bien dans le logiciel arduino.
    Du coup, dans la matrice maliste à quoi correspond entre chaque accolade le numéro et la lettre ?
    Merci

  5. #25
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Citation Envoyé par hugobeauce Voir le message
    Du coup, dans la matrice maliste à quoi correspond entre chaque accolade le numéro et la lettre ?

    Dans mon exemple j’avais pris une structure pour montrer que la fonction pouvait mélanger un groupe de données

    Il suffit d’adapter le type des données du tableau dans la fonction

    ----
    Citation Envoyé par hugobeauce Voir le message
    Au temps pour moi,
    Dans le simulateur tinkercad, votre code plante et ça fonctionne bien dans le logiciel arduino.
    oui TinkerCad a un vieux compilateur C++ qui n'est pas à jour du tout...
    Dans la fonction imprime() j'utilisais ce que l'on appelle un "Range-based for loop" - ça fait partie du standard C++11 publié le 12 août 2011.... il y a déjà plus de 8 ans et demi...

    Dans le code ci dessous je reviens à une bonne vieille boucle for avec un indice et devrait fonctionner dans TinkerCad
    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
    struct donnee_t {
      uint8_t numeroPin;
      char caractere;
    } maListe[] = {
      {0, 'a'}, {1, 'z'}, {2, 'e'}, {3, 'r'}, {4, 't'},
      {5, 'y'}, {6, 'u'}, {7, 'i'}, {8, 'o'}, {9, 'p'}
    };
     
    const size_t nombreDeDonnees = sizeof(maListe) / sizeof(maListe[0]);
     
    void imprime()
    {
      for (size_t i = 0; i < nombreDeDonnees; i++) {
        Serial.print(F("{"));
        Serial.print(maListe[i].numeroPin);
        Serial.print(F(","));
        Serial.print(maListe[i].caractere);
        Serial.print(F("} "));
      }
     
      Serial.println();
    }
     
    void melange()
    {
      // algo cf https://fr.wikipedia.org/wiki/Mélange_de_Fisher-Yates
      for (size_t i = nombreDeDonnees - 1; i >= 1; --i) {
        size_t j = random(0, i + 1);
        donnee_t echange = maListe[i];
        maListe[i] = maListe[j];
        maListe[j] = echange;
      }
    }
     
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));
      imprime();
    }
     
    void loop() {
      delay(1000);
      melange();
      imprime();
    }
    et si vous voulez le même code qui mélange un tableau d'entier, ça ressemblerait à cela:

    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
    int maListe[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
     
    const size_t nombreDeDonnees = sizeof(maListe) / sizeof(maListe[0]);
     
    void imprime()
    {
      for (size_t i = 0; i < nombreDeDonnees; i++) {
        Serial.print(maListe[i]);
        Serial.print(F(" "));
      }
     
      Serial.println();
    }
     
    void melange()
    {
      // algo cf https://fr.wikipedia.org/wiki/Mélange_de_Fisher-Yates
      for (size_t i = nombreDeDonnees - 1; i >= 1; --i) {
        size_t j = random(0, i + 1);
        int echange = maListe[i];
        maListe[i] = maListe[j];
        maListe[j] = echange;
      }
    }
     
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));
      imprime();
    }
     
    void loop() {
      delay(1000);
      melange();
      imprime();
    }

  6. #26
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    Donc si j'essai d'adapter votre code à celui de jpbbricole. UNIQUEMENT pour les ports LED, un message d'erreur dans le setup (certainement un format de variable)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char* filsNoms[] = {"Vert", "Rouge", "Jaune", "Blanc", "Bleu", "xxx"};
     
    #define filsNombre 5                             // Nombre de fils
    #define testNombre 5                             // Nombre de boucles de test
    #define ledOn LOW                                // Quel etat pour allumer la diode
    byte ledsPin[] = {35, 36, 37, 38 , 39};                 // Liste des ports des LED
    byte entreesPin[] = {30, 31, 32, 33 , 34};                // Liste des ports en entrée
    int filsPosition[filsNombre];                    // Position des fils
    ça ferait
    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
    char* filsNoms[] = {"Vert", "Rouge", "Jaune", "Blanc", "Bleu", "xxx"};
     
    #define filsNombre 5                             // Nombre de fils
    #define testNombre 5                             // Nombre de boucles de test
    #define ledOn LOW                                // Quel etat pour allumer la diode
    //byte ledsPin[] = {35, 36, 37, 38 , 39};                 // Liste des ports des LED   <=> remplacé par le tableau maListe ???
    byte entreesPin[] = {30, 31, 32, 33 , 34};                // Liste des ports en entrée
    int filsPosition[filsNombre];                    // Position des fils
     
    struct donnee_t {
      uint8_t ledsPin;
      char caractere;
    } ledsPin[] = {
      {35}, {36}, {37}, {38}, {39},       // Liste des ports des LED
      };
     
    const size_t nombreDeDonnees = sizeof(ledsPin) / sizeof(ledsPin[0]);

    Juste pour être sur; j'ai remplacé maListe par ledsPin et je ne fait apparaitre que le numéro Pin

    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
    void imprime()
    {
      for (const auto& d : ledsPin) {
        Serial.print(F("{"));
        Serial.print(d.ledsPin);
        //Serial.print(F(","));
       // Serial.print(d.caractere);
        Serial.print(F("} "));
      }
      Serial.println();
    }
     
    void melange()
    {
      // algo cf https://fr.wikipedia.org/wiki/Mélange_de_Fisher-Yates
      for (size_t i = nombreDeDonnees - 1; i >= 1; --i) {
        size_t j = random(0, i + 1);
        donnee_t echange = ledsPin[i];
        ledsPin[i] = ledsPin[j];
        ledsPin[j] = echange;
      }
    le setup, j'ai un message d'erreur

    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
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));    ?? A QUOI CA SERT???
     
     melange();    // On brasse les ports Led
    // imprime();    
     
     for (byte i = 0; i < filsNombre; i++)
      {
        pinMode(ledsPin[i], OUTPUT);          //cannot convert 'donnee_t' to 'uint8_t {aka unsigned char}' for argument '1' to 'void pinMode(uint8_t, uint8_t)'
     
        digitalWrite(ledsPin[i], !ledOn);        // Eteindre la LED
        pinMode(entreesPin[i], INPUT_PULLUP);
      }
     
    }
    }
    et la fin du code pour tester la connexion
    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
    void loop()
    {
      filsPositionRecherche();
     
      for (byte fils = 0; fils < filsNombre; fils++)
      {
        if (filsPosition[fils] == fils)                    // Si le fil est à la bonne place            
        {digitalWrite(ledsPin[fils], ledOn);}              // Allumage de la LED 
        else
        {digitalWrite(ledsPin[fils], !ledOn);}             // Allumage de la LED
      }
     
      Serial.print("\n");
      for (byte fils = 0; fils < filsNombre; fils++)         // Affichage des couleurs
      {
        Serial.print((String)filsNoms[fils] + "\t");
      }
      Serial.print("\n");
     
      /*--------------------------------------------------------------------
        Affichafe des couleurs en fonction de la connexion du fil
        Si couleur an MAJUSCULES le fil est bin connecté
        Si couleur en minusciles, le fil est connecté, mais pas à sa place
        Si xxx, le fil n'est pas connecté.
      ----------------------------------------------------------------------
      */
      for (byte fils = 0; fils < filsNombre; fils++)         // Affichage des couleurs selon bra
      {
        Serial.print(filEtat(fils) + "\t");
      }
      Serial.print("\n");
     
      delay(1000);
    }
     
    String filEtat(byte filIndex)                              // Retourne l'état du fil
    {
      String returnValeur = (String)filsNoms[filsPosition[filIndex]];
      returnValeur.toLowerCase();
     
      if (filsPosition[filIndex] == filIndex)                // Si fil en bonne position
      {
        returnValeur.toUpperCase();
      }
     
      return returnValeur;
    }
    void filsPositionRecherche()                               // Recherche de la position des fils                              
    {
      for (byte fils = 0; fils < filsNombre; fils++)
      {
        filsPosition[fils] = filsNombre;
        for (byte entree = 0; entree < filsNombre; entree++)
        {
          byte compteurTest = 0;
          for (byte t = 0; t < testNombre; t++)                                   // Boucle de test
          {
            digitalWrite(ledsPin[fils], !digitalRead(ledsPin[fils]));           // Inverser la LED
            if (digitalRead(entreesPin[entree]) == digitalRead(ledsPin[fils]))  // Entre = etat LED ?
            {compteurTest ++;}
          }
     
          if (compteurTest == testNombre)                                         // Si une connexion a été trouvée
          {
            filsPosition[fils] = entree;                                        // Mémoriser l'entrée
            break;
          }
        }
      }
    }

  7. #27
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Hugo
    cette erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pinMode(ledsPin[i], OUTPUT);          //cannot convert 'donnee_t' to 'uint8_t {aka unsigned char}' for argument '1' to 'void pinMode(uint8_t, uint8_t)'
    provient du fait que cette ligne est en remarque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //byte ledsPin[] = {35, 36, 37, 38 , 39};                 // Liste des ports des LED   <=> remplacé par le tableau maListe ???
    Mets ton code en entier pour faciliter la recherche d'erreurs.

    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  8. #28
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct donnee_t {
      uint8_t ledsPin;
      char caractere;
    } ledsPin[] = {
      {35}, {36}, {37}, {38}, {39},       // Liste des ports des LED
      };
    euh, là c'est le programmation casino... vous ne pouvez pas taper n'importe quoi au hasard et espérer que ça fonctionne... il y a une syntaxe et une grammaire au langage de programmation, vous devez les respecter...

    en reprenant l'approche de JP pour détecter le bon fil, voici un petit code qui fait le mélange et relance un nouveau jeu quand on a trouvé.

    Vous y verrez une petite machine à état dans la loop() qui sert à savoir dans quelle phase du jeu on se trouve.

    le câblage des pins/LEDs et la détection est fondé sur l'approche proposée par JP (j'ai mis que 3 fils dans le code) et le mélange ne se fait que sur les pins "pinDestination" (ça suffit)
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    /*
     
      Câblage
     
      _______
             |
             |
        Dest O-----<<-----[]     (INPUT_PULLUP)
             |
             |
         Src O----->>-----[]     (OUTPUT)
             |         |
             |         |
             |         -
      _______|       [LED]
                       +
                       |
                    [R220]
                       |
                       |
                      +5V
     
      quand on met Src à LOW  (LED_ON),  la LED s'allume
      quand on met Src à HIGH (LED_OFF), la LED s'éteint
     
      Si on relie []*de Src et []*de Dest et que Src est LOW (LED_ON), la LED s'allume et DEST voit LOW
      Si on relie []*de Src et []*de Dest et que Src est HIGH (LED_OFF), la LED s'éteint et DEST voit HIGH
     
    */
     
    #define LED_OFF HIGH
    #define LED_ON LOW
     
    // les pins à mettre en correspondance
    const uint8_t pinLEDSource[]  = {30, 32, 34};
    uint8_t pinDestination[] = {31, 33, 35}; // pas const car on va le mélanger
    const size_t nombreDeFils = sizeof(pinLEDSource) / sizeof(pinLEDSource[0]);
     
    enum : uint8_t {NOUVEAU_JEU, JEU_EN_COURS, VICTOIRE} etat;
     
     
    void imprime()
    {
      for (size_t i = 0; i < nombreDeFils; i++) {
        Serial.print(F("{"));
        Serial.print(pinLEDSource[i]);
        Serial.print(F(" <<->> "));
        Serial.print(pinDestination[i]);
        Serial.print(F("} "));
      }
      Serial.println();
    }
     
    bool cablageCorrect()
    {
      // on fait clignoter la Source et on regarde si on voit ce signal sur la destination
     
      const uint8_t nombreDeClignotements = 3;
      size_t nbFilsCorrects = 0;
     
      for (size_t unFil = 0; unFil < nombreDeFils; unFil++) {
        bool erreur = false;
     
        for (uint8_t n = 0; n < nombreDeClignotements; n++) {
          digitalWrite(pinLEDSource[unFil], LED_ON);
          erreur = (digitalRead(pinDestination[unFil]) != LED_ON);
          if (erreur) break;
          digitalWrite(pinLEDSource[unFil], LED_OFF);
          erreur = (digitalRead(pinDestination[unFil]) != LED_OFF);
          if (erreur) break;
        }
        if (erreur) {
          digitalWrite(pinLEDSource[unFil], LED_OFF);
        } else {
          // le fil est bon on laisse la LED allumée
          digitalWrite(pinLEDSource[unFil], LED_ON);
          nbFilsCorrects++;
        }
      } // fin de pour chaque fil
      return (nbFilsCorrects == nombreDeFils);
    }
     
    void melange()
    {
      // algo cf https://fr.wikipedia.org/wiki/Mélange_de_Fisher-Yates
      for (size_t i = nombreDeFils - 1; i >= 1; --i) {
        size_t j = random(0, i + 1);
        uint8_t echange = pinDestination[i];
        pinDestination[i] = pinDestination[j];
        pinDestination[j] = echange;
      }
    }
     
    // -----------------
     
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));
     
      for (size_t i = 0; i < nombreDeFils; i++) {
        pinMode(pinLEDSource[i], OUTPUT);
        digitalWrite(pinLEDSource[i], LED_OFF);
        pinMode(pinDestination[i], INPUT_PULLUP);
      }
     
      etat = NOUVEAU_JEU;
    }
     
    void loop()
    {
      switch (etat) {
     
        case NOUVEAU_JEU:
          melange();
          imprime();
          etat = JEU_EN_COURS;
          break;
     
        case JEU_EN_COURS:
          if (cablageCorrect()) etat = VICTOIRE;
          delay(500);
          break;
     
        case VICTOIRE:
          Serial.println(F("VICTOIRE"));
          for (uint8_t n = 0; n < 20; n++) {
            for (size_t i = 0; i < nombreDeFils; i++)
              digitalWrite(pinLEDSource[i], LED_OFF);
            delay(50);
            for (size_t i = 0; i < nombreDeFils; i++)
              digitalWrite(pinLEDSource[i], LED_ON);
            delay(50);
          }
          etat = NOUVEAU_JEU;
          break;
      }
    }
    bien sûr là le jeu est facile car la console dit quelles pins connecter ensemble et pour trouver il suffit de tester avec chaque fil les LEDs et elle s'allume si c'est la bonne case.

    Pour rendre cela plus difficile on peut ne pas allumer la LED une fois le fil à la bonne place ou allumer un nombre de LEDs égal au nombre de bonne connexions mais pas forcément en face de chaque fil

  9. #29
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    [QUOTE=jpbbricole;11380534]
    provient du fait que cette ligne est en remarque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //byte ledsPin[] = {35, 36, 37, 38 , 39};                 // Liste des ports des LED   <=> remplacé par le tableau maListe ???
    Si je retire // ça met un conflit avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct donnee_t {
      uint8_t ledsPin;
      char caractere;
    } ledsPin[] = {
      {35}, {36}, {37}, {38}, {39},       // Liste des ports des LED
      };
    Bon je vais me pencher sur le nouveau code de mister JayM

    en tout cas merci à vous deux pour votre soutien, et vos réponses hyper rapides et adaptées à mon niveau de (non)programmation.

  10. #30
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Hugo
    Petit problème de syntaxe, je sais c'est pas toujours évident, le C.
    Pour déclarer la structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define  filsNombre 5
     
    struct donneeDef 
    {
    	uint8_t ledsPin[filsNombre]={35, 36, 37, 38, 39};
    	uint8_t EntreesPin[filsNombre]={30, 31, 32, 33 , 34};
    };
    donneeDef mesDonnees;
    Pour l'usage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     for (byte i = 0; i < filsNombre; i++)
     {
    	 pinMode(mesDonnees.ledsPin[i], OUTPUT);          //cannot convert 'donnee_t' to 'uint8_t {aka unsigned char}' for argument '1' to 'void pinMode(uint8_t, uint8_t)'
     
    	 digitalWrite(mesDonnees.ledsPin[i], !ledOn);        // Eteindre la LED
     	 pinMode(mesDonnees.EntreesPin[i], INPUT_PULLUP);          
    }
    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  11. #31
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Bonsoir Hugo
    Petit problème de syntaxe, je sais c'est pas toujours évident, le C.
    Pour déclarer la structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct donneeDef 
    {
    	uint8_t ledsPin[filsNombre]={35, 36, 37, 38, 39};
    	uint8_t EntreesPin[filsNombre]={30, 31, 32, 33, 34};
    } mesDonnees;
    il manque juste mesDonnees non ?

    votre approche fonctionne car est une structure en C++ est une classe.

    En pratique (et en C) on ne donne pas les valeurs dans la déclaration de structure (c'est un type, donc pas de valeur générique) donc on fera plutôt la définition du type, puis ensuite on peut faire des affectations (en valeur de départ). donc on écrira
    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
    const byte filsNombre = 5;
    struct donneeDef
    {
      uint8_t ledsPin[filsNombre];
      uint8_t EntreesPin[filsNombre];
    };
     
    donneeDef mesDonnees1 = {
      {1, 2, 3, 4, 5},
      {5, 7, 8, 9, 10}
    };
     
    donneeDef mesDonnees2 = {
      {11, 12, 13, 14, 15},
      {15, 17, 18, 19, 20}
    };
     
    void setup() {
      Serial.begin(115200);
      for (byte i = 0; i < filsNombre; i++) {
        Serial.print(mesDonnees1.ledsPin[i]);
        Serial.write(' ');
        Serial.println(mesDonnees1.EntreesPin[i]);
      }
     
      Serial.println();
     
      for (byte i = 0; i < filsNombre; i++) {
        Serial.print(mesDonnees2.ledsPin[i]);
        Serial.write(' ');
        Serial.println(mesDonnees2.EntreesPin[i]);
      }
    }
     
    void loop() {}

    car si on essaye de compiler
    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
    const byte filsNombre = 5;
    struct donneeDef
    {
      uint8_t ledsPin[filsNombre]={35, 36, 37, 38, 39};
      uint8_t EntreesPin[filsNombre]={30, 31, 32, 33, 34};
    };
     
    donneeDef mesDonnees1 = {
      {1, 2, 3, 4, 5},
      {5, 7, 8, 9, 10}
    };
     
    donneeDef mesDonnees2 = {
      {11, 12, 13, 14, 15},
      {15, 17, 18, 19, 20}
    };
     
    void setup() {
      Serial.begin(115200);
      for (byte i = 0; i < filsNombre; i++) {
        Serial.print(mesDonnees1.ledsPin[i]);
        Serial.write(' ');
        Serial.println(mesDonnees1.EntreesPin[i]);
      }
     
      Serial.println();
     
      for (byte i = 0; i < filsNombre; i++) {
        Serial.print(mesDonnees2.ledsPin[i]);
        Serial.write(' ');
        Serial.println(mesDonnees2.EntreesPin[i]);
      }
    }
     
    void loop() {}
    le compilateur ne va pas être d'accord et vous dire

    error: could not convert '{{1, 2, 3, 4, 5}, {5, 7, 8, 9, 10}}' from '<brace-enclosed initializer list>' to 'donneeDef'

  12. #32
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir
    Citation Envoyé par Jay M Voir le message
    il manque juste mesDonnees non ?
    Oupsss, c'est corrigé!

    Citation Envoyé par Jay M Voir le message
    votre approche fonctionne car est une structure en C++ est une classe.
    "L'Arduino" c'est pas un dérivé du C++?

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  13. #33
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Bonsoir
    "L'Arduino" c'est pas un dérivé du C++?
    si, c'est même le langage C++

    mais tel que vous l'avez codé ça marche pour 1 élément --> essayez de créer 2 ou 3 variables de ce type avec votre approche en ne gardant qu'un seul "type" mais des valeurs initiales différentes.

  14. #34
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Jay M

    Oui, j'ai constaté, mais c'est quand même pratique pour créer et "remplir" des tableaux dans une structure.
    Quel est la bonne méthode?

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  15. #35
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Dans une structure c’est comme je l’ai fait. On met entre accolades les éléments qui correspondent aux types de bases, en groupant entre accolades si c’est un tableau

    Vous avez créé une classe avec des variables de type tableau qui ont une valeur par défaut

  16. #36
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Jay M

    Merci, j'avais mal lu ton message #31.

    Bonne nuit.
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  17. #37
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 715
    Points : 5 394
    Points
    5 394
    Par défaut
    Pas de souci.

    Pour résumer, si on a un tableau à initialiser on met des accolades et dedans les valeurs séparées par des virgules et on finit l’expression par un point virgule.
    Si c’est un tableau à une dimension pas la peine de déclarer la taille, le compilateur la déduit par la liste fournie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int tableauInt[] = {1, 2, 3, 4, 5};
    char tableauChar[] = {’a’, ’b’, ’c’};
    Un tableau à deux dimensions est un tableau de tableaux. Par exemple tableau a 3 éléments qui sont de type tableau à 4 éléments. Donc on applique le même principe, on met les éléments dans les accolades, séparés par des virgules
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int tableau[3][4] = {sous_tableau0, sous_tableau1, sous_tableau2};
    et comme les sous_tableaux sont aussi des tableaux, idem on met les éléments dans les accolades, séparés par des virgules, donc on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int tableau[3][4] = {{1,2,3,4}, {11,12,13,14}, {21,22,23,24}};
    et on a vu qu'on a pas besoin de donner la taille du tableau le plus externe car le compilateur sait compter le nombre d'éléments donc on pourrait même écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int tableau[][4] = {{1,2,3,4}, {11,12,13,14}, {21,22,23,24}};

    Si maintenant le la tableau contient un type composé comme une structure, on définit d’abord le type - purement formellement - quels sont les types de données qui vont le constituer, puis ensuite on crée une variable de ce type et pour l’initialiser on groupe encore chaque élément de structure dans des accolades.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // definition du type
    struct monType {
      int a;
      int b;
    };
     
    // création d’une variable de ce type 
    monType var = {10, 20};  // var.a vaut 10 et var.b vaut 20
    On a donc une paire d’accolade pour grouper les éléments de structure et une paire d’accolade pour grouper les éléments d’un tableau
    Si maintenant on veut un tableau dont les éléments sont des structures, on combine les 2 approches: On met un groupe d’accolades pour le tableau puis les éléments du tableau les uns à la suite des autres séparés par des virgules. Ici comme ces éléments sont des structures, on a vu qu’on les met aussi entre accolades

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // definition du type
    struct monType {
      int a;
      int b;
    };
    
    // création d’une variable De type tableau de ce type 
    monType tableauMonType[] = {  // cette accolade pour l’ouverture des éléments du tableau
      {10, 20}, // premier élément du tableau, il est de type struct donc on liste ses éléments dans l’ordre entre accolades 
      {11, 21}, // deuxième élément du tableau
      {12, 22} // troisième élément du tableau
    }; // accolade de fin du tableau
    On aura donc tableauMonType[0].a qui vaut 10 ou tableauMonType[2].b qui vaut 22

    Et si un des éléments de la structure est lui aussi de type composé , comme un tableau ou une autre structure, on applique le même principe, on liste les données entre accolades.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // definition du type
    struct monType {
      int unTableau[3]; // on est obligé de donner une taille fixe
      int a;
      int b;
    };
    
    // création d’une variable De type tableau de ce type 
    monType tableauMonType[] = {  // cette accolade pour l’ouverture des éléments du tableau pour la variable tableauMonType
      {{9,8,7}, 10, 20}, // premier élément du tableau, il est de type struct donc on liste ses éléments dans l’ordre entre accolades 
      {{19,18,17},  11, 21}, // deuxième élément du tableau
      {{29,28,27},  12, 22} // troisième élément du tableau
    }; // accolade de fin du tableau
    On aura donc tableauMonType[0].unTableau[2] qui vaut 7

    voilà il suffit de bien regarder la structure et de mettre les valeurs entre accolades, séparées par des virgules, dans le bon ordre et si la valeur correspond à un type composé, on met le groupe de valeurs entre accolades, séparées par des virgules. C’est une définition extensible on peut avoir un tableau de structure qui contient des structures qui contiennent des tableaux etc...

  18. #38
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par Jay M Voir le message


    euh, là c'est le programmation casino... vous ne pouvez pas taper n'importe quoi au hasard et espérer que ça fonctionne... il y a une syntaxe et une grammaire au langage de programmation, vous devez les respecter...

    en reprenant l'approche de JP pour détecter le bon fil, voici un petit code qui fait le mélange et relance un nouveau jeu quand on a trouvé.

    Vous y verrez une petite machine à état dans la loop() qui sert à savoir dans quelle phase du jeu on se trouve.

    le câblage des pins/LEDs et la détection est fondé sur l'approche proposée par JP (j'ai mis que 3 fils dans le code) et le mélange ne se fait que sur les pins "pinDestination" (ça suffit)

    Pour rendre cela plus difficile on peut ne pas allumer la LED une fois le fil à la bonne place ou allumer un nombre de LEDs égal au nombre de bonne connexions mais pas forcément en face de chaque fil
    Merci pour ce code qui répond largement à mes attentes, effectivement nul besoin de mélanger Pin destination et Pin entrées. Pour ma part, cette discussion est donc belle et bien résolue.
    Encore une fois, un grand merci à toi et jpbbricole pour votre aide. J'adore ce site pour cette raison.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Projets informatique : les bonnes pratiques
    Par elitost dans le forum Débats sur le développement - Le Best Of
    Réponses: 345
    Dernier message: 18/10/2011, 16h08
  2. [PROJET] Recherche développeur C/C++ et autres
    Par 4R416N33² dans le forum Autres
    Réponses: 0
    Dernier message: 29/07/2007, 04h59
  3. [projet] recherche d'inspiration
    Par gorgonite dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 09/10/2006, 20h57
  4. PHP ORACLE ? Recherche une bonne methode
    Par Torando59 dans le forum Oracle
    Réponses: 4
    Dernier message: 24/01/2006, 12h54

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