Go Down

Topic: Mesure de vitesse sur un plan incliné (diode SFH4546 et récepteur TSOP31238) (Read 186 times) previous topic - next topic

iToine

Bonjour à tous,

Afin de montrer à mes élèves qu'une bille a une vitesse plus importante sur un plan incliné de 30° que de 10°, auparavant j'utilisait un pied réglable en hauteur par un système de vis, et un calendrier en carton et je faisais chronométrer les élèves.
Le canabis et l'excès de téléphone portable ayant des effets notoires sur le cerveau et indirectement sur le temps de réaction, un élève qui chronomètre va trouver un coup 0,873s pour une distance de 50cm, et la fois d'après 3,234s.
J'ai regardé sur les catalogues fournisseurs de matériel, mais leurs solutions étaient hors de prix (je suis regardant des dépenses de l'argent public!).
J'ai donc réfléchi et vu que j'avais un starter kit arduino je me suis lancé.
J'ai essayé une première fois avec des photorésistances mais c'était extrêmement sensible aux variations de lumière.
J'ai donc cherché un peu et je me suis tourné vers une solution infrarouge.

Partie 1 : Fonctionnement du récepteur TSOP31238
Le récepteur possède 3 pattes qu'il faut câbler comme indiqué sur le schéma ci-dessous.

Pour tester le bon fonctionnement, je prends une télécommande infrarouge classique, j'appuie sur un bouton, et le code hexadécimal correspondant s'affiche dans le moniteur série.
Par exemple, un code obtenu après appui sur un bouton: 12:10:30.241 -> 17B00FF
Chaque bouton a un code différent évidemment.
Le code correspondant:
Code: [Select]

#include <IRremoteInt.h>

#include <IRremote.h> // On inclut la librairie IRremote.h
int receiver = 11; // On branche le TSOP31238 sur le pin Digital #11
IRrecv irrecv(receiver); // Création de l'instance 'irrecv'
decode_results results;

void setup()
{
  Serial.begin(115200); // Ouverture du port série à la bonne vitesse
  irrecv.enableIRIn(); // Démarrage du récepteur
  pinMode(9, OUTPUT); // Déclaration de la diode rouge branchée en digital #9 en tant qu'élément de sortie
 
}
void loop()
{
  if (irrecv.decode(&results)) // Test pour voir si on reçoit un signal
  {
    Serial.println(results.value, HEX); // Affichage du code hexadecimal
    digitalWrite(9, HIGH); //Allumage de la diode rouge
    delay(500); // Attente de 500ms
    digitalWrite(9, LOW); // Extinction de la diode rouge
    irrecv.resume();// Reception de la valeur suivante   
  }
}


Partie 2 : Fonctionnement de la diode IR SFH4546
Pour tester si la diode fonctionne, on peut par exemple essayer d'allumer une télévision ou un ampli avec le code correspondant à la touche ON/OFF de la télécommande.
Pour cela, on récupère le code comme vu en Partie 1.
Le montage est le suivant.

Le code est le suivant:
Code: [Select]
/*
  Emission infrarouge
*/

#include <IRremote.h>

IRsend emission_ir; // crée une instance

void setup()
{
  Serial.begin(115200); // Ouverture du port série à la bonne vitesse
  pinMode(9, OUTPUT); // Déclaration de la diode rouge branchée en digital #9 en tant qu'élément de sortie
}

void loop()
{
  emission_ir.sendNEC(0x3fc609f, 32); // code télécommande CGV on/off
  digitalWrite(9, HIGH); //Allumage de la diode rouge
  delay(500); // Attente de 500ms
  digitalWrite(9, LOW); // Extinction de la diode rouge
  delay(5000);
}


Partie 3 :Barrière infrarouge

Une barrière est composée par un couple Emetteur / Détecteur qui doivent être alignés au mieux.
Dans mon cas, je veux deux barrières:
  • Une barrière de départ qui une fois franchie lancera un chronomètre
  • Une barrière d'arrivée qui une fois franchie stoppera le chronomètre

L'affichage du temps entre les deux barrières se fait sur le moniteur série et sur un LCD branché en I2C.
Un bouton poussoir sert à effacer le LCD et à passer à la mesure suivante.
Le schéma est le suivant:

Et le code:
Code: [Select]

/*
 Double barrière infrarouge permettant de mesurer la vitesse d'une bille sur un plan incliné
 Les LED IR  sont branchées en parallèle sur D3 (géré par librairie IRremote)
 Le détecteur IR TSOP32138 est branché en D12
*/
// HIGH --> Coupure de la barrière
// LOW --> Fermeture de la barrière
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
#include <IRremote.h>

#define CAPTEURDEPART 4 // Récepteur IR départ -> D4
#define CAPTEURARRIVEE 5 // Récepteur IR arrivée -> D5

const int buttonPin = 6;     // crée un identifiant pour la broche utilisée avec le BP
const int ledPin =  13;      // crée un identifiant pour la broche utilisée avec la LED
int buttonState = 0;         // variable pour mémoriser l'état du bouton

IRsend irsend; // déclaration de l'objet émetteur (pin D3 obligatoire)

void setup()
{
 lcd.begin();        // Initialisation du LCD
 lcd.backlight();    // allumer retroeclairage
 lcd.clear();
 pinMode(CAPTEURDEPART, INPUT); // Déclaration du capteur de départ en INPUT
 pinMode(CAPTEURARRIVEE, INPUT); // Déclaration du capteur d'arrivée en INPUT
 irsend.enableIROut(38); // Création d'une sortie modulée à 38KHz
 Serial.begin(115200);
 lcd.print("Appuyer bouton");
 Serial.println("Attente mesure..");
}

void loop()
{
 static unsigned long Debut_Chrono = 0;
 static unsigned long Fin_Chrono = 0;
 static bool debutChrono = false;
 static bool finChrono = false;
 static bool initialisation = false;

 irsend.mark(0); // Envoi du signal IR pour une durée illimitée
 delay(5);
   buttonState = digitalRead(buttonPin);
   if (buttonState == HIGH) {
     debutChrono = true;
     initialisation=true;
     Serial.println("Attente mesure..");
     lcd.clear();
     lcd.print("Attente mesure..");
   }



 if (debutChrono) {
   if (digitalRead(CAPTEURDEPART) == LOW) { // FERMETURE de la barrière de départ car la bille est devant et la coupe!
     Debut_Chrono = millis();
     Serial.println("Lancement du chronomètre... ");
     lcd.clear();
     lcd.print("Mesure en cours");
     debutChrono = false;
     finChrono = true;
   }
 }
 else {
   if (finChrono) {
     if (digitalRead(CAPTEURARRIVEE) == HIGH) { // Coupure de la barrière d'arrivée
       Fin_Chrono = millis();
       Serial.println("...arrêt du chronomètre");
       unsigned long duree = Fin_Chrono - Debut_Chrono;
       Serial.print("Temps:");
       Serial.print((duree / 1000) % 60);
       Serial.print("sec ");
       Serial.print( duree % 1000);
       Serial.println("''");
       lcd.clear();
       lcd.print("Temps:");
       lcd.print((duree / 1000) % 60);
       lcd.print("sec ");
       lcd.print( duree % 1000);
       lcd.println("''");
       finChrono = false;
     }
   }

 }
}


Voilà!
cela fonctionne parfaitement. Les mesures ne semblent pas être perturbées par la lumière ambiante, et semblent reproductible. Je vais tester la reproductibilité dans la semaine et je vous dirai.
Le topic où j'ai posé les questions pour ce projet se trouve ici si besoin.

Go Up