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 :

Création d'un Convoyeur de tri avec Arduino


Sujet :

Arduino

  1. #1
    Nouveau Candidat au Club
    Création d'un Convoyeur de tri avec Arduino
    Bonjour,
    je cherche à créer un convoyeur pour trier des pièces de longueurs différentes.
    ARDUINO + LASER + CAPTEUR LASER + RELAIS PNEUMATIQUE
    J'obtiens de bon résultat avec ce code pour definir la taille des pièces

    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
     
    const byte btnPin = 2;        // Bouton sur pin 2...
    const byte btnIrq = 0;       // Bouton sur pin 2, soit INT0 sur arduino UNO.
    unsigned long tFall = 0;     // Valeur de millis() lors du front descendant
    unsigned long tRise = 0;    // Valeur de millis() lors du front montant
    unsigned long tDiff =0;     //Valeur appuie Bp
    void onRise(void);
    void onFall(void);
    void setup(void);
    void loop(void);
    void onFall() {                                     // Interruption lors d'un front descendant
    tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
    attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
    }
    void onRise() {                                     // Interruption lors d'un front montant
    tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
    attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
    }
    void setup(void) {                                  // Setup:
    attachInterrupt(btnIrq, onFall, FALLING);        // Détection d'interruption sur front descendant au départ
    Serial.begin(115200);                           // Serial à 11500 bauds
    }
    void loop(void) {
    if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
    tDiff= tRise - tFall;
    Serial.println(tDiff);
    tFall=0;tRise=0;tDiff=0;
    /*Serial.print("tRise=");
    Serial.println(tRise);
    Serial.print("tFall=");
    Serial.println(tFall);                   // Si les 2 fronts ont été détectés, alors on affiche tout
    Serial.print("tDiff=");*/
    }
    }




    Cependant je n'arrive pas à donner un déclenchement sur le Pin 8 en fonction de la valeur de tDiff ( compris entre deux valeurs )

    Le pin 8 Active un relais ( AIR ).

    Pouvez vous m'aider ?

    Voici mon script, il fonctionne mais une pièce sur deux ( quelque soit l'intervalle de temps de passage )
    A l'oscilloscope, chaque passage de pièce est bien présent ( le capteur OK )

    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
     
    // DECLARATION DES CAPTEURS
    int air = 8; // vers relais AIR
    const byte cap = 2; // vers CAPTEUR LASER
    const byte btnIrq = 0;
     
    // DETECTION DES FRONTS
     
    static unsigned long tFall = 0;         // Valeur de millis() lors du front descendant
    static unsigned long tRise = 0;        // Valeur de millis() lors du front montant
    unsigned long tDiff = 0;       //Valeur appuie Bp
    unsigned long mem;            //Variable mémoire
     
    //SETUP
    void onRise(void);
    void onFall(void);
    void setup(void);
    void loop(void);
     
    void onFall()
    {                                     // Interruption lors d'un front descendant
      tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
      attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
     
    }
     
    void onRise()
    {                                     // Interruption lors d'un front montant
    tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
    attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
     
    }
     
    void setup(void)
    {
    // PULLUP  
    pinMode(cap, INPUT_PULLUP);
     
    //
    pinMode(air, OUTPUT);
    attachInterrupt(btnIrq, onFall, FALLING);         // Détection d'interruption sur front descendant au départ
    ///////////////////
    Serial.begin(115200);                              // Serial à 9600 bauds
    }
    void loop(void) {
     
    digitalWrite(air, LOW);
    noInterrupts();
     
    ///////////////0  
    if ( ( tRise != 0 ) && ( tFall != 0 ) )
    {
            tDiff = ( tRise - tFall );
            mem = tDiff;        
    }
    interrupts();
     
    if ( mem > 150 && mem < 300  )
    {            
    Serial.println(tDiff);
    //  Serial.println(tDiff);
    //Serial.println(tFall);
    //Serial.println(tRise);
    digitalWrite(air, HIGH);
    delay(300); // EXPULSION DE LA PIECE
    //   digitalWrite(air, LOW);
    mem = 0; tFall = 0; tRise = 0; tDiff = 0; // REMISE A ZERO 
     
     
    }}

  2. #2
    Membre éprouvé
    Bonjour bot27210

    Je n'ai pas pu essayer "en vrai" mais j'ai réorganisé, un peu le void loop() 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
    27
    28
    29
    30
    31
    32
     void loop(void) {
     
    	 digitalWrite(air, LOW);
    	 noInterrupts();
     
    	 ///////////////0
    	 if ( ( tRise != 0 ) && ( tFall != 0 ) )
    	 {
    		 tDiff = ( tRise - tFall );
    		 tFall = 0; tRise = 0; // REMISE A ZERO
    		 mem = tDiff;
    	 }
    	 interrupts();
     
    	 if (mem > 0)
    	 {
    		if ( mem > 150 && mem < 300  )
    		{
    			Serial.println(tDiff);
    			//  Serial.println(tDiff);
    			//Serial.println(tFall);
    			//Serial.println(tRise);
    			 digitalWrite(air, HIGH);
    			delay(300); // EXPULSION DE LA PIECE
    			//   digitalWrite(air, LOW); 
    		}
     
    		// Mettre d'autres conditions
     
    		mem = 0; // REMISE A ZERO
    	 }
    }

    J'ai déplacé la mise à 0 de tRise et tFall. Dans ta version, ils n'étaient remis à 0 seulement quand la condition if ( ( tRise != 0 ) && ( tFall != 0 ) ) était remplie alors, que pour moi, même sans cette condition, du moment qu'une mesure était complète et enregistrée (tDiff), ils devaient l'être.
    A essayer...

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

  3. #3
    Expert éminent sénior
    bonjour,

    1- est-ce que ton relais peut-être piloté par une sortie Arduino ?

    2- Ensuite je reste perplexe sur ta manière de gérer les interruptions :
    Code arduino :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
    void onFall()
    {                                     // Interruption lors d'un front descendant
        tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
        attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
    }
     
    void onRise()
    {                                     // Interruption lors d'un front montant
        tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
        attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
    }
     
    void setup(void)
    {
        attachInterrupt(btnIrq, onFall, FALLING);         // Détection d'interruption sur front descendant au départ                           
    }


    Il aurait été plus judicieux d'utiliser l'événement CHANGE dans ton cas plutôt que redéfinir tes interruptions lors de chaque changement d'état. Par défaut, ou quand ton système démarre, ton entrée interruptible est à l'état haut ou à l'état bas ?

    La documentation recommande cette syntaxe pour le premier argument :
    https://www.arduino.cc/reference/en/...tachinterrupt/
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    attachInterrupt( digitalPinToInterrupt(btnIrq), onChange, CHANGE)