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. #1
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut Projet : Recherche de bonne connectique
    bonjour à vous,
    je souhaite réaliser un jeu où la personne doit relier les bonnes extrémités de fils pour rétablir un relais (fictif).
    le joueur ne voit pas les couleurs bien évidement.

    Nom : connect.png
Affichages : 112
Taille : 2,2 Ko

    il faut donc relier bleu avec bleu et la led bleue s'allume; ainsi de suite pour les autres couleurs.

    Est-ce que c'est possible avec une carte Arduino?
    Pour moi si tu pars de GRD quelque soit l'extrémité, le circuit s'ouvre et la led s'allumera???

    je n'arrive pas à me représenter le circuit électrique, ni s'il faut utiliser du numérique ou analogique.

    Merci beaucoup pour votre aide

  2. #2
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    c'est faisable avec un arduino, mais bien sûr si vous fermez un circuit il vous faut quelque part un élément différentiateur sur le circuit.

    il y a plusieurs options mais par exemple vous pouvez jouer sur la notion de circuit diviseur de tension et faire une mesure analogique (analogRead()) au milieu des deux résistances

    Nom : idee4.png
Affichages : 105
Taille : 52,4 Ko

    pour mémoire dans un circuit diviseur
    Nom : circuit.png
Affichages : 99
Taille : 9,6 Ko
    on aura U2 défini par la formule
    Nom : U2.png
Affichages : 99
Taille : 9,5 Ko

    avec R2 identique du côté droit et des résistance (Rouge, Bleue, Jaune, Verte) R1 en série (elles peuvent êtres identiques) et bien choisies de l'autre côté, vous pourrez savoir en lisant les tension sur les pins analogiques quel fil est branché.

    (le fil rouge aura qu'une simple résistance R1, la résistance équivalente vue par le fil jaune en amont est (2 x R1) car elles sont en série, celle du fil bleu est (3 x R1) etc...)

    ----

    sinon vous pouvez jouer avec 4 pins en OUTPUT qui émettent un signal à une fréquence particulière
    par exemple:
    le fil rouge pourrait être HIGH 1ms puis LOW 4ms
    le fil bleu pourrait être HIGH 2ms puis LOW 4ms
    le fil jaune pourrait être HIGH 3ms puis LOW 2ms
    le fil vert pourrait être HIGH 4ms puis LOW 1ms

    et 4 pins en INPUT-PULLUP qui servent de pin de branchement

    pin Dx (OUTPUT) ----- Resistance de limitation de courant ------> fil à brancher pin branchement (INPUT-PULLUP)

    la loop() écouterait en permanence les pins de branchement:
    - quand rien n'est branché la pin de branchement voit HIGH en permanence car elle est en PULLUP
    - quand vous branchez un fil, elle voit le signal tel qu'émis par la pin d'origine.

    et pour ne pas surcharger votre micro-contrôleur et gérer le changement d'état des pins de sorties, au lieu de prendre des temps comme déclarés ci dessus, prenez des pins PWM et affectez leur un signal différent par analogWrite() dans le setup(), comme ça la boucle peut se contenter d'écouter la durée du signal HIGH

    comme le PWM est à ~500Hz ou 1000Hz suivant les pins sur UNO (voir la référence analogWrite), la durée d'un HIGH attendu sera très courte et donc d'un point de vue de l'utilisateur c'est comme si tout était fait en temps réel alors que vous allez écouter chaque pin l'une après l'autre.

    --> étudiez la fonction pulseIn() pour lire la durée du signal haut (avec un timeout)


    -----

    il y aurait d'autres options mais ces deux là sont fonctionnelles et simples à mettre en oeuvre si vous voulez un Arduino au milieu.

    Sinon sans arduino et avec des circuits indépendants, il suffit que la LED soit sur le circuit que vous fermez (vous créez autant de circuits indépendants que nécessaire).

    Nom : sans.png
Affichages : 92
Taille : 31,3 Ko

    et vous avez le jeu de « questions‐réponses » qu'on fabrique en primaire où il faut associer deux bons fils

  3. #3
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    bonjour, merci pour ce retour.

    toujours dans la thématique si j'ai bien compris,

    le montage serait le suivant

    Nom : analogread.png
Affichages : 96
Taille : 85,9 Ko

    Le fils avec la flèche, est celui à bien connecter.

    Au niveau du programme, on aurait quelque chose du type.

    If analogread (fils orange)==1000 (au pif);
    alors la led rouge s'allume //connectée à un pin digital?
    … idem pour les autres fils

  4. #4
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    presque, il faut que la mesure analogique soit au milieu des 2 résistances (et au calcul mathématique près)
    Nom : gnd.png
Affichages : 95
Taille : 45,3 Ko


    Attention à ne pas mettre les résistances dans un des 2 rails externe de la breadboard:
    Nom : rail.png
Affichages : 89
Taille : 16,4 Ko
    sur la majorité des breadboards les pins sont déjà connectées entre elles en horizontal à ce niveau (et il y a une ligne bleue et une ligne rouge pour marquer cette continuité)
    Nom : ligne.png
Affichages : 93
Taille : 77,5 Ko

    (au passage —*si ça peut-être utile —*la lecture de la tension sur une des pin Ax vous dira quel fil a été connecté. ça vous permet éventuellement de donner des indications à l'utilisateur pour l'aider à corriger son erreur)

  5. #5
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    bon j'ai corrigé mon circuit (effectivement court-circuit assuré), j'avais même oublié de mettre à la GRD.

    Nom : analogread.png
Affichages : 94
Taille : 51,1 Ko

    vous confirmez que c'est bon ( mon maître LOL).

    (au passage —*si ça peut-être utile —*la lecture de la tension sur une des pin Ax vous dira quel fil a été connecté. ça vous permet éventuellement de donner des indications à l'utilisateur pour l'aider à corriger son erreur)
    Je n'en suis pas rendu là, mais un vilain buzzer en cas de mauvais branchement, pour faire monter le cardio c'est top.

  6. #6
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    voilà, j'ai fait le code avec mon simulateur Tinkercad.

    R1=330 ohm
    R2=200 ohm

    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 analogPin1 = A1; 
    int analogPin2 = A2; 
    int analogPin3 = A3; 
    int analogPin4 = A4; 
    int analogPin5 = A5; 
     
    int val1 = 0; // variable de type int pour stocker la valeur de la mesure
    int val2 = 0;
    int val3 = 0;
    int val4 = 0;
    int val5 = 0;
     
    void setup()
    {
      Serial.begin(9600);          //  initialisation de la connexion série
    // IMPORTANT : la fenêtre terminal côté PC doit être réglée sur la même valeur. 
    }
     
    void loop()
    {
     
      // lit la valeur de la tension analogique présente sur la broche
      val1 = analogRead(analogPin1);  
      val2 = analogRead(analogPin2);
      val3 = analogRead(analogPin3);
      val4 = analogRead(analogPin4);
      val5 = analogRead(analogPin5);
     
       // affiche la valeur (comprise en 0 et 1023) dans la fenêtre terminal PC
      Serial.println(val1); 
      Serial.println(val2);
      Serial.println(val3);
      Serial.println(val4);
      Serial.println(val5);
     
    }
    En résultat j'ai 305/91/28/11/0 (bizarre d'avoir valeur nulle???)

    du coup dans mon projet il va falloir dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    If (val1==305){
    allume led1;}        //en ayant déclaré les pins avant
    If (val2==91){
    allume led2;}        //en ayant déclaré les pins avant
    If (val3==28){
    allume led3;}        //en ayant déclaré les pins avant
    If (val4==11){
    allume led4;}        //en ayant déclaré les pins avant
    If (val5==0){
    allume led5;}        //en ayant déclaré les pins avant

  7. #7
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Quel est le schéma de connexion ?

  8. #8
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    Il est dans le message d'avant

  9. #9
    Membre éprouvé
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    février 2013
    Messages
    422
    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 : 422
    Points : 1 064
    Points
    1 064
    Par défaut
    Bonjour

    Une autre approche, numérique, du sujet. En gros, je fais clignoter une sortie (ledsPin), qui me sert de LED d'indication et je reprends cette sortie sur une entrée (entreesPin), compte le nombre de clignotements (testNombre) si le comptage est OK, le fil est à la bonne place et la LED correspondante s'allume (Les LED s'allument avec un LOW (#define ledOn LOW)) et, dans le moniteur, la couleur du fil s'affiche (filsNoms[]) en MAJUSCULES.

    rouge BLEU jaune vert
    rouge BLEU jaune vert
    rouge BLEU jaune vert
    rouge BLEU jaune VERT
    rouge BLEU jaune VERT
    rouge BLEU jaune VERT
    rouge BLEU jaune VERT
    rouge BLEU jaune VERT

    Le reste est dans le programme.
    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
    char* filsNoms[] = {"rouge", "bleu", "jaune", "vert"};
     
    #define filsNombre 4                             // Nombre de fils
    #define testNombre 4                             // Nombre de boucles de test
    #define ledOn LOW                                // Quel etat pour allumer la diode
    byte ledsPin[] = {8, 9, 10, 11};                 // Liste des ports des LED
    byte entreesPin[] = {4, 5, 6, 7};                // Liste des ports en entrée
     
    void setup()
    {
    	Serial.begin(115200);
     
    	for (byte i = 0; i < filsNombre; i++)
    	{
    		pinMode(ledsPin[i], OUTPUT);
    		digitalWrite(ledsPin[i], !ledOn);        // Eteindre la LED
    		pinMode(entreesPin[i], INPUT_PULLUP);
    	}
     
    }
     
    void loop()
    {
    	for (byte i = 0; i < filsNombre; i++)
    	{
    		byte compteurTest = 0;
    		for (byte t = 0; t < testNombre; t++)                             // Boucle de test
    		{
    			digitalWrite(ledsPin[i], !digitalRead(ledsPin[i]));           // Inverser la LED
    			if (digitalRead(entreesPin[i]) == digitalRead(ledsPin[i]))    // Entre = etat LED ?
    			{
    				compteurTest ++;
    			}
    		}
    		if (compteurTest == testNombre)                                   // Si le fil est à la bonne place            
    		{
    			digitalWrite(ledsPin[i], ledOn);                              // Allumage de la LED 
    		} 
    		else
    		{
    			digitalWrite(ledsPin[i], !ledOn);                             // Allumage de la LED
    		}
     
    	}
    	for (byte i = 0; i < filsNombre; i++)
    	{
    		String filEtat = (String)filsNoms[i] + " ";
    		if (digitalRead(ledsPin[i]) == ledOn)                               // Si le fil est à la bonne place                          
    		{
    			filEtat.toUpperCase();                                          // Etat du fil en majuscules
    		} 
    		Serial.print(filEtat);
    	}
     
    	Serial.print("\n");
    	delay(1000);
    }
    et le schéma
    Nom : ARDDEV_hugobeauce_JeuxFils.png
Affichages : 81
Taille : 15,9 Ko
    Petite question à Jay M, quel programme utilises-tu pour faire les schémas que tu publies?

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

  10. #10
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Petite question à Jay M, quel programme utilises-tu pour faire les schémas que tu publies?
    Bonne approche aussi (même pas besoin des LEDs d'ailleurs mais ça fait joli )

    Pour mes dessins c'est assez simple, comme je suis sur un mac j'utilise les soft gratuits fournis avec l'OS (pages, keynote, voire juste aperçu) qui ont des fonctions de dessin super simples. Je fais mon dessin et je l'exporte sous forme d'image PNG avec fond transparent que je charge ici.

    Il doit y avoir quelque chose Approchant sur Linux avec les outils de dessin Writer dans OpenOffice pour créer des objets graphiques

  11. #11
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par hugobeauce Voir le message
    bon j'ai corrigé mon circuit (effectivement court-circuit assuré), j'avais même oublié de mettre à la GRND
    ça a l'air mieux oui

    pour le code il faudrait tester sur une marge d'erreur car analogRead() ne va pas toujours donner la même valeur à 1 ou 2 près. en fait vous pouvez presque dire si valeur > xxx rien de branché sinon si > v1 alors tel fil, sinon si > v2 alors tel fil, sinon si > v3 tel fil sinon si > v4 tel fil sinon rien de bon

  12. #12
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    En fait c'est assez fastidieux car hier soir je me suis rendu compte qu'en fonction des combinaisons de fils connectés, les valeurs différent.
    Et plus il y a de fils et plus le nombre de combinaisons augmente.
    Je vais donc regarder s'il n'y a pas de superposition de plage de valeur.
    Merci pour ce conseil.

  13. #13
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par hugobeauce Voir le message
    En fait c'est assez fastidieux car hier soir je me suis rendu compte qu'en fonction des combinaisons de fils connectés, les valeurs différent.
    Et plus il y a de fils et plus le nombre de combinaisons augmente.
    Je vais donc regarder s'il n'y a pas de superposition de plage de valeur.
    Merci pour ce conseil.
    Sinon l'approche de jpbricole ou le PWM+pulsein décrit ci dessous (qui en gros fait la même chose "sans faire clignoter à la main") vous évitera toutes ces résistances

    super-jpbricole - fidèle à lui même - a même eu l'amabilité de pousser le boulot pour vous donner le code qui va bien !

  14. #14
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    hello,
    merci jpbbricole, je viens de réaliser le circuit sur mon simulateur, ça marche au poil, sans prise de tête.
    Un grand merci pour votre soutient

  15. #15
    Membre éprouvé
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    février 2013
    Messages
    422
    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 : 422
    Points : 1 064
    Points
    1 064
    Par défaut
    Bonsoir Hugo

    Je me suis "amusé" à faire une version qui te dis si un câble est connecté ou pas et s'il est à sa place ou pas:
    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
    char* filsNoms[] = {"Rouge", "Bleu", "Jaune", "Vert", "xxx"};
     
    #define filsNombre 4                             // Nombre de fils
    #define testNombre 4                             // Nombre de boucles de test
    #define ledOn LOW                                // Quel etat pour allumer la diode
    byte ledsPin[] = {8, 9, 10, 11};                 // Liste des ports des LED
    byte entreesPin[] = {4, 5, 6, 7};                // Liste des ports en entrée
    int filsPosition[filsNombre];                    // Position des fils
     
    void setup()
    {
    	Serial.begin(115200);
     
    	for (byte i = 0; i < filsNombre; i++)
    	{
    		pinMode(ledsPin[i], OUTPUT);
    		digitalWrite(ledsPin[i], !ledOn);        // Eteindre la LED
    		pinMode(entreesPin[i], INPUT_PULLUP);
    	}
     
    }
     
    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;
    			}
    		}
    	}
    }
    Un tout petit plus compliqué mais plus efficace.

    Rouge Bleu Jaune Vert
    ROUGE jaune bleu xxx
    Rouge est juste
    Jaune et Bleu sont croisée
    Vert n'est pas connecté

    Si tu veux plus de fils, tu peux étendre les entrées/sorties au moyen de circuits MCP23017.

    A toi de jouer!
    Bonne soirée
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  16. #16
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    Ah oui tu t'amuses.
    Je vais rester simple avec que des leds.
    Du coup led fixe = ok
    Led petit cligno = non connecté
    Led grand cligno = mauvais branchement
    Je vais essayer d'adapter ton code.

    Perso, j'ai une carte mega donc pas trop impacté par le nombre de sorties. Je me base un mini de 6 et maxi de 8 fils.
    Merci pour ton aide.

  17. #17
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    Est-il possible au début d'utiliser la fonction random, de façon qu'à chaque partie, les connections soient différentes?

    ça ferait qqcose comme ça:

    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
     
     
    while (i <=Nb led,++i){
    [case1]{
    randomSeed(1,4)=X;  //on attribue un chiffre à la première led
    A=X;
    ++i;
    break;}
    [case2]{
    randomSeed(1,4)=X;
    if (X<>A) {B=X;++i;break;} else {break;}  // Si valeur Led2 différente Led1 alors ok sinon, on relance la boucle pour Led2
    ….    // ainsi de suite pur toutes les leds. On peut aussi faire cette technique pour le pin de contrôle et augmenter les combinaisons
     
     
    byte ledsPin[] = {A, B, C, D};                 // on applique les numéros de borne appliquées aux leds
    byte entreesPin[] = {E, F, G, H};

  18. #18
    Membre éprouvé
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    février 2013
    Messages
    422
    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 : 422
    Points : 1 064
    Points
    1 064
    Par défaut
    Bonjour Hugo
    Citation Envoyé par hugobeauce Voir le message
    Est-il possible au début d'utiliser la fonction random, de façon qu'à chaque partie, les connections soient différentes?
    Oui, en mélangeant, au hasard le tableau entreesPin, ainsi
    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
     
    /*-----------------------------------------------
    '*	Remplissage d'un tableau sans doublons
    '*-----------------------------------------------
    */
    void entreesPinMelange()
    {
    	byte rndNumber;
    	byte rndIndex = 0;
    	boolean rndTest[filsNombre];                                // Pour tester su la valeur est déjà tirée
     
    	for (byte r = 0; r < filsNombre; r++)                       // Tout le tableau de test à false
    	{rndTest[r] = false;}
     
    	while(rndIndex < filsNombre)
    	{
    		randomSeed(analogRead(0));                              // Réinitialiser RND de l'Arduino
    		rndNumber = random(0, filsNombre);
    		if (rndTest[rndNumber] == false)                        // Si nombre hasard pas déjà tiré
    		{
    			entreesPin[rndIndex] = entreesPinBase[rndNumber];   // Mettre la pin dans le tableau de travail
    			rndTest[rndNumber] = true;                          // Enregistrer le numéro comme tiré
    			rndIndex ++;
    		}
    	}
    }
    Ca donne ceci (pour le tableau byte entreesPinBase[] = {4, 5, 6, 7})
    5746
    4675
    6475
    4675
    7645
    6547
    4567
    5764
    6574
    Tu peux améliorer le hasard en mettant un petit bout de fil (~5cm) sur l'entrée A0 (randomSeed(analogRead(0)))

    Le programme modifié donne ceci (je n'ai pas pu tout essayer, sauf le générateur aléatoire)
    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
    char* filsNoms[] = {"Rouge", "Bleu", "Jaune", "Vert", "xxx"};
     
    #define filsNombre 4                             // Nombre de fils
    #define testNombre 4                             // Nombre de boucles de test
    #define ledOn LOW                                // Quel etat pour allumer la diode
    byte ledsPin[] = {8, 9, 10, 11};                 // Liste des ports des LED
    byte entreesPinBase[] = {4, 5, 6, 7};            // Liste des ports en entrée position de base
    byte entreesPin[filsNombre];                     // Liste des ports en entrée de travail, éventuellement mélangé
    int filsPosition[filsNombre];                    // Position des fils
     
    #define entreesMalangees true                    // S'il faut mélanger les entrées
     
    void setup()
    {
    	Serial.begin(115200);
     
    	for (byte i = 0; i < filsNombre; i++)
    	{
    		pinMode(ledsPin[i], OUTPUT);
    		digitalWrite(ledsPin[i], !ledOn);        // Eteindre la LED
    		pinMode(entreesPin[i], INPUT_PULLUP);
     
    		entreesPin[i] = entreesPinBase[i];       // Entrées fils dans tableau de travail
    	}
     
    	if (entreesMalangees) {entreesPinMelange();}	 
    	for (byte r = 0; r < filsNombre; r++)
    	{
    		Serial.print(entreesPin[r]);
    	}
    	Serial.println("");
    }
     
    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;
    			}
    		}
    	}
    }
     
    /*-----------------------------------------------
    '*	Remplissage d'un tableau sans doublons
    '*-----------------------------------------------
    */
    void entreesPinMelange()
    {
    	byte rndNumber;
    	byte rndIndex = 0;
    	boolean rndTest[filsNombre];                                // Pour tester su la valeur est déjà tirée
     
    	for (byte r = 0; r < filsNombre; r++)                       // Tout le tableau de test à false
    	{rndTest[r] = false;}
     
    	while(rndIndex < filsNombre)
    	{
    		randomSeed(analogRead(0));                              // Réinitialiser RND de l'Arduino
    		rndNumber = random(0, filsNombre);
    		if (rndTest[rndNumber] == false)                        // Si nombre hasard pas déjà tiré
    		{
    			entreesPin[rndIndex] = entreesPinBase[rndNumber];   // Mettre la pin dans le tableau de travail
    			rndTest[rndNumber] = true;                          // Enregistrer le numéro comme tiré
    			rndIndex ++;
    		}
    	}
    }
    Je te laisse découvrir les différences.

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

  19. #19
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Bonjour Hugo

    Oui, en mélangeant, au hasard le tableau entreesPin, ainsi
    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
     
    /*-----------------------------------------------
    '*    Remplissage d'un tableau sans doublons
    '*-----------------------------------------------
    */
    void entreesPinMelange()
    {
        byte rndNumber;
        byte rndIndex = 0;
        boolean rndTest[filsNombre];                                // Pour tester su la valeur est déjà tirée
     
        for (byte r = 0; r < filsNombre; r++)                       // Tout le tableau de test à false
        {rndTest[r] = false;}
     
        while(rndIndex < filsNombre)
        {
            randomSeed(analogRead(0));                              // Réinitialiser RND de l'Arduino
            rndNumber = random(0, filsNombre);
            if (rndTest[rndNumber] == false)                        // Si nombre hasard pas déjà tiré
            {
                entreesPin[rndIndex] = entreesPinBase[rndNumber];   // Mettre la pin dans le tableau de travail
                rndTest[rndNumber] = true;                          // Enregistrer le numéro comme tiré
                rndIndex ++;
            }
        }
    }
    Salut

    l'inconvenient de cette approche pour le mélange (tirage unique) des éléments d'un tableau c'est que sa durée est non déterministe, vous dépendez du hasard pour converger et vous risquez de tester plein de fois une case déjà affectée. Si le tableau est grand (N données), vers la fin quand il ne vous reste plus qu'une valeur vous n'avez qu'une chance sur N de tomber dessus par hasard pour l'affecter. (2 chances sur N quand il en reste 2 etc).

    C'est une problématique assez classique que de devoir extraire une fois et une seule les entrées d'un tableau de manière aléatoire et l'algorithme dit du mélange de Fisher-Yates (1938 !!) permet de traiter cela sans tableau supplémentaire, avec une complexité linéaire et donne statistiquement toutes les permutations avec la même probabilité.

    Voici un bout de code qui montre comment ça marche (implémentation de l'algorithme décrit sur wikipedia).

    j'ai pris un tableau de structures pour montrer qu'on peut traiter simplement un groupe de données et pas juste un tableau de type de base.

    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
    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 (const auto& d : maListe) {
        Serial.print(F("{"));
        Serial.print(d.numeroPin);
        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 = maListe[i];
        maListe[i] = maListe[j];
        maListe[j] = echange;
      }
    }
     
    void setup() {
      Serial.begin(115200);
      randomSeed(analogRead(A0));
      imprime();
    }
     
    void loop() {
      delay(1000);
      melange();
      imprime();
    }

    sur la console on verra

    {0,a} {1,z} {2,e} {3,r} {4,t} {5,y} {6,u} {7,i} {8,o} {9,p} <== celle du départ dans le code avant mélange
    {3,r} {4,t} {6,u} {8,o} {9,p} {5,y} {2,e} {7,i} {1,z} {0,a}
    {3,r} {4,t} {1,z} {2,e} {0,a} {5,y} {8,o} {6,u} {9,p} {7,i}
    {1,z} {5,y} {2,e} {4,t} {8,o} {3,r} {7,i} {0,a} {6,u} {9,p}
    {4,t} {2,e} {8,o} {0,a} {3,r} {9,p} {5,y} {6,u} {7,i} {1,z}
    {3,r} {2,e} {8,o} {4,t} {6,u} {7,i} {5,y} {1,z} {9,p} {0,a}
    {6,u} {7,i} {9,p} {5,y} {2,e} {1,z} {4,t} {8,o} {3,r} {0,a}
    {0,a} {2,e} {5,y} {6,u} {4,t} {9,p} {3,r} {8,o} {7,i} {1,z}
    {6,u} {3,r} {5,y} {1,z} {0,a} {2,e} {4,t} {8,o} {9,p} {7,i}
    {9,p} {6,u} {1,z} {2,e} {0,a} {4,t} {5,y} {8,o} {7,i} {3,r}
    ...

    chaque ligne représente une permutation des 10 entrée

  20. #20
    Membre éprouvé
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    février 2013
    Messages
    422
    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 : 422
    Points : 1 064
    Points
    1 064
    Par défaut
    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
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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, 17h08
  2. [PROJET] Recherche développeur C/C++ et autres
    Par 4R416N33² dans le forum Autres
    Réponses: 0
    Dernier message: 29/07/2007, 05h59
  3. [projet] recherche d'inspiration
    Par gorgonite dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 09/10/2006, 21h57
  4. PHP ORACLE ? Recherche une bonne methode
    Par Torando59 dans le forum Oracle
    Réponses: 4
    Dernier message: 24/01/2006, 13h54

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