Detecter la coupure d’un faisceau (partie 2)

Fichier hébergé par Archive-Host.com

La même idée mais en utilisant un capteur de distance infrarouge. Le programme est très semblable au précédent. Quand un objet est placé dans le champ d’observation du capteur le buzzer retentit.
Ce qui se passe : le capteur retourne une valeur entre 0 et 1023 en fonction de la distance qui le sépare de l’objet mis en face de lui. Dans ce montage le capteur « voit » la poutrelle plate fixe et renvoie une valeur qui fluctue un peu autour de 220.
Si on met un objet plus proche, cette valeur va augmenter : on fixe à 250 le seuil à partir duquel on décide qu’un objet est vu. Idéalement, l’objet doit être placé en face de la lentille du capteur, à plus ou moins deux trous de l’axe médian de la plaque. Un objet trop près du capteur ou de la poutrelle plate ne sera pas détecté.

On remarque que le câblage est très simple. Un inconvénient : le prix du capteur, environ une dizaine d’euros. Attention, il existe différents modèles de capteurs Sharp, il faut choisir pour cette application un modèle avec distance minimale de mesure faible (ici 4 cm).


// Detecter la coupure d'un faisceau à l'aide d'un capteur
// de distance IR
 
// on utilise un capteur infrarouge 
// Sharp GP2D120XJ00F (4-30cm)

 
int IRPin = 0;        // le capteur est connecté à la pin  a0 et
                      // au 5 v et à la masse
                          
int IRmesure;        // la valeur lue de 0 à 1023

int pin_son = 11;     // le buzzer est relié à la pin 11

int LA= 55;           // la note jouée par le buzzer


int nblect=3; // nb de lectures faites, on va faire une moyenne
int moyenne=0;

int seuil = 250 ; // si la valeur analogique lue est supérieure à 250
                  // on déclenchera le buzzer

void setup(void) {
  
  Serial.begin(19200);   
}
 
void loop(void) {    

  int i;
  
  moyenne=0; // on va faire la moyenne de plusieurs mesures
  
  for (i=0 ; i < nblect ; i++) {  
   moyenne = moyenne + analogRead(IRPin);  
   // le capteur ne peut pas mesurer plus vite
   // il faut attendre entre deux mesures
   delay(40);
  }
   
  IRmesure = moyenne / nblect;
    
  Serial.print("Mesure = ");
  Serial.println(IRmesure);      
  
  
  if (IRmesure > seuil) { // objet proche
      sonnette_on();
  } else {
      sonnette_off();
  }   
 
} // loop


// fonctions /////////////////////////////////////////////

void sonnette_on () {
  
  tone (pin_son,LA);
}

void sonnette_off () {
  
  noTone (pin_son);
}

Detecter la coupure d’un faisceau (partie 1)

Damien, un des lecteurs de ce blog, m’a donné l’idée de me pencher sur le sujet. Voici une première approche avec une photoresistance et une LDR (resistance qui varie avec la quantité de lumière reçue). Quand le faisceau est coupé par un obstacle, le buzzer retentit. Il s’arrête quand il n’y a plus d’obstacle.

Je pensais avoir de gros soucis avec la lumière ambiante. En fait je trouve que cela fonctionne bien, et cela a l’avantage de ne nécessiter que des composants simples et très bon marché. On peut améliorer la detection en confectionnant par exemple avec du ruban adhésif un petit cabochon autour de la LDR pour la rendre moins sensible à la lumière ambiante.

Voici le programme :


/* Photocell 2. 
 
Voir les bases sur  http://learn.adafruit.com/photocells */

// une LED emet de la lumière vers une photoresistance
// si le faisceau lumineux est coupé
// un buzzer se déclenche

// schema émetteur

// +5v -----[R 220 ohms]------LED------0v

// schema récepteur

// +5v---LDR--+-----[R 4700 ohms]------0v
//            |
//            A0


 
int photocellPin = 0; // la photoresistance est connectée à la pin  a0, d'un coté
                      // au 5 v de l'autre coté
                          
int photocellmesure;  // la valeur lue de 0 à 1023

int pin_son = 11;     // le buzzer est relié à la pin 11

int LA= 55;           // la note jouée par le buzzer


int nblect=20; // nb de lectures faites, on va faire une moyenne
int moyenne=0;

int seuil = 600 ; // si la valeur analogique lue est inférieure à 600
                  // on déclenchera le buzzer

void setup(void) {
  
  Serial.begin(19200);   
}
 
void loop(void) {    

  int i;
  
  moyenne=0; // on va faire la moyenne de plusieurs mesures
  
  for (i=0 ; i < nblect ; i++) {  
   moyenne = moyenne + analogRead(photocellPin);  
  }
   
  photocellmesure = moyenne / nblect;
    
  Serial.print("Mesure = ");
  Serial.println(photocellmesure);      
  
  
  if (photocellmesure < seuil) { // faisceau coupé !
      sonnette_on();
  } else {
      sonnette_off();
  }   
 
} // loop


// fonctions /////////////////////////////////////////////

void sonnette_on () {
  
  tone (pin_son,LA);
}

void sonnette_off () {
  
  noTone (pin_son);
}

Fichier hébergé par Archive-Host.com

Côté diode émettrice, rien de sorcier, la diode est en série avec une résistance de 220 ohms. Le tout est raccordé d’un côté au +5v, de l’autre au 0v (GND).

Côté LDR, on utilise une résistance pulldown de 4700 ohms, le schéma de montage peut-être déduit de la photo. C’est la borne analogique A0 (câble jaune) qui mesure la tension entre la LDR et le 0v. L’Arduino convertit cette tension en une valeur entre 0 et 1023. Si la valeur de cette tension lue chute trop bas, c’est que la LDR présente une resistance élevée ce qui arrive quand elle ne reçoit pas assez de lumière, c’est à dire quand un obstacle est placé entre la LED emettrice et la LDR réceptrice.

Servo et boutons poussoirs (partie 3)

Fichier hébergé par Archive-Host.com

Cette fois ci, on n’utilise pas des entrées digitales (une par bouton) mais on va utiliser une seule entrée analogique pour lier l’Arduino à un clavier 5 touches. Ici j’ai choisi un clavier de chez DFRobot (DFR0075). Dans ce montage on a besoin seulement de 4 touches, la cinquième n’est pas utilisée.
L’idée est que lorsque l’on appuie sur une touche donnée on déclenche l’envoi de la tension correspondante sur l’entrée analogique. Sur le site de DFRobot on trouve un petit programme qui permet de lire efficacement l’appui sur les différentes touches. Je l’ai repris pour l’essentiel et combiné avec les programmes précédents.


// Servo BP4
// à l'aide d'un clavier 5 touches DFRobot
// commander deux servo-moteurs (touches + et -)


// ok pour  DFRDuino Romeo V1.1

// variables speciales lecture clavier 5 touches

// methode trouvée sur le site de DFRobot
//ADKeyboard Module
//Developed by DFRobot.com
//Last modified 30/11/2011
//Version 1.0

// Tableau des valeurs correspondantes
// à chaque touche

int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
// le clavier est relié à l'entree analogique 0
int analogpin=0;


#include <Servo.h>
   
// H : servo horizontal 
// V : servo vertical

Servo myservoH; // un objet de type servo est crée (max 8 objets servo)

Servo myservoV; // un objet de type servo est crée (max 8 objets servo)

int pmin = 0; // position mini

int pmax = 180 ; // position  maxi

int pactH= 90 ; // position actuelle

int pactV= 90 ; // position actuelle

void tourne_plusH ()          
{
  if ( pactH < pmax) {    
      pactH = pactH + 1;   
      myservoH.write(pactH);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}   
    
void tourne_moinsH ()          
{
  if ( pactH > pmin) {    
      pactH = pactH - 1;   
      myservoH.write(pactH);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}    

void tourne_plusV ()          
{
  if ( pactV < pmax) {    
      pactV = pactV + 1;   
      myservoV.write(pactV);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}   
    
void tourne_moinsV ()          
{
  if ( pactV > pmin) {    
      pactV = pactV - 1;   
      myservoV.write(pactV);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}    
    
 
void setup() // executée une seule fois

{
    
    myservoH.attach(9); // attache le servo H à la pin 9
    
    myservoV.attach(10); // attache le servo H à la pin 10  
       
    Serial.begin(19200);    
      
}


void loop() // executée en boucle
{         
           
  adc_key_in = analogRead(0);    // read the value from the sensor 

  key = get_key(adc_key_in);  // convert into key press
  

    delay(50);  // wait for debounce time
    adc_key_in = analogRead(analogpin);    // read the value from the sensor 
    key = get_key(adc_key_in);    // convert into key press
   
      if (key >=0){
        switch(key)
        {
           case 0:Serial.println("S1 OK");   
                 break;
           case 1:Serial.println("S2 OK");   
                  tourne_moinsH();          
                  break;
           case 2:Serial.println("S3 OK");   
                  tourne_plusH();
                  break;
           case 3:Serial.println("S4 OK");   
                  tourne_plusV();
                  break;                        
           case 4:Serial.println("S5 OK");  
                   tourne_moinsV(); 
                  break;  
        }                
      }        
          
          
          
}
  
// Convert ADC value to key number
int get_key(unsigned int input)
{
    int k;
    for (k = 0; k < NUM_KEYS; k++)
    {
      if (input < adc_key_val[k])
     {
            return k;
        }
     }
       if (k >= NUM_KEYS)
           {k = -1;  // No valid key pressed
            return k;
            }

}

Cela fonctionne pas mal du tout… mais on s’aperçoit d’une perte de fonctionalité : on ne peut pas appuyer sur deux boutons en même temps c’est à dire concrètement touner la base et lever la flèche… Le clavier est fait pour lire un appui sur une touche à la fois et pas deux en même temps.

Servo et boutons poussoirs (partie 2)

Sur la plate-forme précédente qui permettait une rotation dans le plan horizontal, on monte un second servo qui va permettre de monter et descendre une flèche de grue dans un plan vertical. On ajoute deux boutons poussoirs pour contrôler ce mouvement.

Il existe des servo plus petits pour ceux qui aimeraient construire une grue encore plus compacte. Il existe aussi des servos à rotation continue, non limités à un angle de rotation de 180°.

Fichier hébergé par Archive-Host.com

Le programme se déduit sans peine de la version précédente.



// Servo BP2 
// à l'aide de deux series de deux boutons poussoirs + et -
// commander deux servo-moteurs

// ok pour  DFRDuino Romeo V1.1

#include <Servo.h>
   
// H : servo horizontal 
// V : servo vertical

Servo myservoH; // un objet de type servo est crée (max 8 objets servo)

Servo myservoV; // un objet de type servo est crée (max 8 objets servo)

int pinMoinsH = 4;  // reliée au bouton poussoir "-"

int pinPlusH = 3 ;  //  reliée au bouton poussoir "+"

int pinMoinsV = 5;  // reliée au bouton poussoir "-"

int pinPlusV = 6 ;  //  reliée au bouton poussoir "+"

int pmin = 0; // position mini

int pmax = 180 ; // position  maxi

int pactH= 90 ; // position actuelle

int pactV= 90 ; // position actuelle

int appui= 0; // quand un bouton poussoir est appuye il est dans l'état bas, 0v


void tourne_plusH ()          
{
  if ( pactH < pmax) {    
      pactH = pactH + 1;   
      myservoH.write(pactH);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}   
    
void tourne_moinsH ()          
{
  if ( pactH > pmin) {    
      pactH = pactH - 1;   
      myservoH.write(pactH);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}    

void tourne_plusV ()          
{
  if ( pactV < pmax) {    
      pactV = pactV + 1;   
      myservoV.write(pactV);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}   
    
void tourne_moinsV ()          
{
  if ( pactV > pmin) {    
      pactV = pactV - 1;   
      myservoV.write(pactV);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}    
    
 
void setup() // executée une seule fois

{
    
    myservoH.attach(9); // attache le servo H à la pin 9
    
    myservoV.attach(10); // attache le servo H à la pin 10
    
    pinMode(pinMoinsH, INPUT);    // Pin en mode entrée  
     
    pinMode(pinPlusH, INPUT);     // Pin en mode entrée     
     
    pinMode(pinMoinsV, INPUT);    // Pin en mode entrée  
     
    pinMode(pinPlusV, INPUT);     // Pin en mode entrée   
   
       
    Serial.begin(19200);    
      
}


void loop() // executée en boucle
{         
    
 if (digitalRead(pinMoinsH) == appui) { // appui sur le bouton poussoir    
    Serial.print("appui sur BP moins H ! ");    
    tourne_moinsH();
    }
    
  if (digitalRead(pinPlusH) == appui) { // appui sur le bouton poussoir 
    Serial.print("appui sur BP plus H ! ");
    tourne_plusH();    
    }     
    
       
 if (digitalRead(pinMoinsV) == appui) { // appui sur le bouton poussoir    
    Serial.print("appui sur BP moins V  ! ");    
    tourne_moinsV();
    }
    
  if (digitalRead(pinPlusV) == appui) { // appui sur le bouton poussoir 
    Serial.print("appui sur BP plus V ! ");
    tourne_plusV();  
    }                  
          
}

Ce petit modèle est sympa à faire fonctionner, les deux mouvements de rotation de la base et de lever de la flèche peuvent être exécutés simultanément.
Les contacts offerts par ces boutons poussoirs dits numériques (ils sont soit à l’état haut, soit à l’état bas mais pas dans un état indéfini) sont francs. Le seul souci est le nombre de fils, on va essayer d’arranger ça dans le prochain article…

Servo et boutons poussoirs (partie 1)

Voici un montage pas compliqué qui permet, avec deux boutons poussoirs, de contrôler finement la rotation d’un plateau monté sur un servo.

On utilise 2 « boutons-poussoirs » de chez DFRobot (DFR0029), très pratiques, ils se câblent sur la carte DFRduino avec les câbles fournis, les trous de fixation sont au pas Meccano ! En fait il ne s’agit pas de boutons-poussoirs ordinaires. Ils ont trois fils 5v,0v, signal. Si on appuie sur le bouton, le signal est relié à 0v sinon à 5V. Cela simplifie le programme (pas besoin d’activer les resistances pull-up) et le montage (condensateurs inutiles), la fixation est en outre bien meilleure qu’avec des boutons poussoirs ordinaires qui ont un peu tendance à se détacher de la breadboard. Bref vraiment à recommander pour avoir un montage simple et solide. Le seul inconvénient : le nombre de fils ! (Nous verrons une autre solution un peu plus tard, où 5 boutons sont disponibles avec trois fils seulement.)

Le bouton de droite fait tourner le plateau dans le sens des aiguilles d’une montre, le bouton de gauche dans le sens inverse.

Le servo peut être positionné de 0 à 180°. Au démarrage, le servo se met à la position milieu (90°) ; on peut tourner de 90° à droite ou de 90° à gauche.

Le servo est alimenté en 5v par une entrée spéciale sur la carte, à proximité du connecteur USB. Si on n’a qu’un petit servo à alimenter on peut se contenter de l’alim USB (qui alimente alors la carte et le servo). Si on veut supprimer le câble USB, il faudra prévoir d’alimenter le carte en 7,5v par la prise jack et le servo en 5v par l’entrée alim servo sur la carte.

Fichier hébergé par Archive-Host.com


// Servo BP1 
// à l'aide de deux boutons poussoirs + et -
// commander un servo-moteur

// ok pour  DFRDuino Romeo V1.1

#include <Servo.h>
   
Servo myservo; // un objet de type servo est crée (max 8 objets servo)


int pinMoins = 4;  // reliée au bouton poussoir "-"

int pinPlus = 3 ;  //  reliée au bouton poussoir "+"

int pmin = 0; // position mini

int pmax = 180 ; // position  maxi

int pact= 90 ; // position actuelle

int appui= 0; // quand un bouton poussoir est appuye il est dans l'état bas 0v


void tourne_plus ()          
{
  if ( pact < pmax) {    
      pact = pact + 1;   
      myservo.write(pact);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}   
    
void tourne_moins ()          
{
  if ( pact > pmin) {    
      pact = pact - 1;   
      myservo.write(pact);      
      delay(50); // attendre 50 ms après chaque changement
    }     
}    
    
 
void setup() // executée une seule fois

{
    
    myservo.attach(9); // attache le servo à la pin 9
    
    pinMode(pinMoins, INPUT);    // Pin en mode entrée  
     
    pinMode(pinPlus, INPUT);    // Pin en mode entrée       
          
    Serial.begin(19200);   
      
}


void loop() // executée en boucle
{
           
 if (digitalRead(pinMoins) == appui) { // appui sur le bouton poussoir    
    Serial.print("appui sur BP moins ! ");    
    tourne_moins();
    }
    
  if (digitalRead(pinPlus) == appui) { // appui sur le bouton poussoir 
    Serial.print("appui sur BP plus ! ");
    tourne_plus();    
    }                  
 }