LOCODUINO

Parlons Arduino => Vos projets => Discussion démarrée par: Cevenol38 le juin 19, 2016, 09:14:42 am

Titre: Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 09:14:42 am
Bonjour à tous,
Je souhaite utiliser le système de barrière infrarouge présenté sur le site pour gérer une coulisse. Le programme de test du site fonctionne très bien avec mon montage et mon Arduino Mega mais lorsque je souhaite utiliser des interruptions rien ne se passe  :(. Peut être que quelque chose m'a échappé sur l'utilisation des interruptions  :o. Voici le code que j'ai testé
#include <PinChangeInt.h>
const byte Test=A0;
const int ledPin = 13;
int cpt=0;
void detect()
{
  cpt++;
}
void vide()
{
  cpt--;
}

void setup()
{
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);     
  pinMode(Test, INPUT_PULLUP);
  PCintPort::attachInterrupt(Test, detect, RISING);
  PCintPort::attachInterrupt(Test, vide, FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (cpt>0)
  {
      digitalWrite(ledPin, HIGH);
      delay(200);
      digitalWrite(ledPin, LOW);
      delay(200);
      digitalWrite(ledPin, HIGH);
      delay(200);   
      digitalWrite(ledPin, LOW);
      delay(200);
   }
   else
   {
    digitalWrite(ledPin, LOW);
    }

}
Titre: Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 10:10:33 am
Bonjour et bienvenue parmi nous.

L'entrée A0 du Mega correspond à la broche (ADC0)PF0 (voir https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf) de l'ATMega 2560. Sur ce même schéma on peut voir à quelle broche correspondent les 24 pin change interrupt :

- 10 à 15
- SCK, MOSI et MISO
- A8 à A15

et 7 qui ne sont pas disponibles sur les connecteurs

Dans la liste, il n'y a pas A0. Ça vient sans doute de là

Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 11:38:59 am
Merci :)
Du coup à quoi correspond le A0 indiqué sur le circuit de la carte ?   :-[ enfin je veux dire par quel numéro est il identifié en terme de programmation ?
Titre: Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 11:42:40 am
C'est identifié par A0 :)

C'est juste que PCintPort::attachInterrupt n'a aucun effet sur cette broche étant donné qu'elle ne peut pas servir de broche d'interruption externe.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 11:45:06 am
OK du coup quelle broche puis je utiliser ? et surtout comment la désigner dans mon programme :) ?
Titre: Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 11:46:37 am
A8 à A15 sont possibles par exemple et je pense qu'il suffit de les appeler par leur nom.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 11:48:41 am
Bon ben je viens de faire un test avec A8 et ça ne change rien :(
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 11:55:23 am
En fait une mesure au multimètre indique un très faible voltage sur ma sortie de circuit 0.28v sans obstacle et 0.06V lorsque il y a un obstacle est ce normal ne devrait on pas retrouver 5V ?
Titre: Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 11:56:20 am
Il est possible que la bibliothèque que vous utilisez ne fonctionne que sur Uno et équivalent (ATMega328). Essayez avec celle-ci qui comporte un exemple pour Mega :

https://github.com/GreyGnome/PinChangeInt
Titre: Re : Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 11:56:50 am
En fait une mesure au multimètre indique un très faible voltage sur ma sortie de circuit 0.28v sans obstacle et 0.06V lorsque il y a un obstacle est ce normal ne devrait on pas retrouver 5V ?

Non ce n'est pas normal.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 12:05:36 pm
Avec cette librairie le prog ne compile pas car non compatible avec arduino mega :(.
Ce qui est curieux c'est que lorsque je débranche la broche la variation de courant est détectée puisque ma led change d'état.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Dominique le juin 19, 2016, 01:24:39 pm
J'ai compilé l'exemple PinChangeIntExample2560 avec succès !
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 02:51:40 pm
Oui autant pour moi, la compilation fonctionne mais cela ne change rien :(. Est ce que cela ne viendrait pas de la résistance de 2.2kohm qui serai trop importante ?
Ce qui est curieux c'est que sans les interruptions cela fonctionne très bien
Titre: Re : Barrière infra rouge et interruptions
Posté par: Jean-Luc le juin 19, 2016, 03:32:01 pm
Essaye de mettre INPUT au lieu d'INPUT_PULLUP.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 06:33:17 pm
Même résultat, finalement j'ai laissé tombé les interruptions et j'ai fait cela autrement en simplement mesurant l'écart de valeur lorsque la barrière est rompue ou pas :) et ça marche très bien.
Voici le code en mode debug pour un seul canton :)
//Affectation des ports
//d'occupation
//const byte detect_v1[]={A0,A1,A2,A3,A4,A5};
const byte detect_v1[]={A0,A0,A0,A0,A0,A0};
//const byte detect_v2[]={A8,A9,A10,A11,A12,A13};
const byte detect_v2[]={A0,A0,A0,A0,A0,A0};
//de disjoncteurs
const int disj_v1[]={23,25,27,29,31,33};
const int disj_v2[]={22,24,26,28,30,32};
//des aiguillages;
const int p_aiguillages[]={34,36,38,40,42};
//Variables globales
// variable de temps en millisecondes
unsigned long liberation_v1[] = {0,0,0,0,0,0};   // derniere fois que le detecteur a changé
unsigned long liberation_v2[] = {0,0,0,0,0,0};   // derniere fois que le detecteur a changé
long Delai_liberation = 1000;   // delai d'une seconde pour valider un changement
int occup_vp1=0;
int occup_vp2=0;
int occup_v1[]={0,0,0,0,0,0};
int occup_v2[]={0,0,0,0,0,0};

//Fonctions
void init_canton(byte voie)
{
  Serial.print("Canton initialisé en mode INPUT");
  Serial.println(voie);
  pinMode(voie,INPUT);
}
void detection(byte canton,int num, int occup, int voie)
{
  int etat=analogRead(canton);
  if (etat>100)
  {
    //un train est détecté la valeur lue est supérieure à 15
    if (occup==0)
    {
      Serial.print("Valeur =");
      Serial.println(etat);
      occupation(canton,num,voie);
    }
  }
  else
  {
    if (occup==1)
    //le canton est libre
    {
     
      Serial.print("Valeur =");
      Serial.println(etat);
      liberation(canton,num,voie);
    }
   
  }
}
void occupation(byte canton,int num, int voie)
{
    if (voie==1)
    {
      occup_v1[num]=1;
      liberation_v1[num]=millis();
      Serial.print("Voie 1 Canton occupe :");
      Serial.println(canton);
    }
    else if(voie==2)
    {
      occup_v2[num]=1;
      liberation_v2[num]=millis();
      Serial.print("Voie 2 Canton occupe :");
      Serial.println(canton);
    }
   
   
}
void liberation(byte canton,int num, int voie)
{
  unsigned long time;
  time=millis();
  if (voie==1)
    {
      if (time-liberation_v1[num] > Delai_liberation)
      {
        occup_v1[num]=0;
        Serial.print("VOIE 1 Canton libre :");
        Serial.println(canton);
      }
    }
    else if(voie==2)
    {
      if (time-liberation_v2[num] > Delai_liberation)
      {
        occup_v2[num]=0;
        Serial.print("VOIE 2 Canton libre :");
        Serial.println(canton); 
      }
     
    }
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);           // set up Serial library at 9600 bps
  //for (int i=0;i<6;i++)
  for (int i=0;i<1;i++)
  {
    init_canton(detect_v1[i]);
   // init_canton(detect_v2[i]);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  //for (int i=0; i<6;i++)
  for (int i=0;i<1;i++)
  {
    detection(detect_v1[i],i,occup_v1[i],1);
    //detection(detect_v2[i],i,occup_v2[i],2);
  }

}
Titre: Re : Barrière infra rouge et interruptions
Posté par: Dominique le juin 19, 2016, 08:25:18 pm
J'ai peut-être compris pourquoi les interruptions ne marchent pas : ce n'est pas un problème logiciel mais matériel !

Sur Arduino, les niveaux logiques sont particuliers (un peu différents de ceux de la TTL et du CMOS) :
(http://www.locoduino.org/IMG/png/5v-logic-levels.png)

Un niveau LOW correspond à une tension inférieure à 1,5V.
Un niveau HIGH correspond à une tension supérieure à 3V.

Dans votre test, int etat=analogRead(canton);
  if (etat>100)  {
    //un train est détecté la valeur lue est supérieure à 15
...
vous décrétez le niveau HIGH à 100 : en proportion sur 1024 pour 5V, 100 correspond à 0,5V. On est en plein dans la plage du niveau bas.

D'ailleurs je ne comprend pas bien à quoi correspond la valeur 15 dans le commentaire.

Ce que vous pouvez faire en analogique, en différenciant 2 tensions faibles, ne peut pas marcher en digital car il faut au moins 3V pour assurer le niveau haut.
Votre montage détecteur IR ne fournit peut-être jamais de niveau haut logique !!!

Cela peut provenir de plusieurs raisons :
- courant trop faible dans la diode émettrice
- distance trop grande entre la diode émettrice et le récepteur
- lumière parasite...

C'est pour cela que j'aime bien travailler en analogique avec ce type de détecteur, ce qui permet l'étalonnage comme je l'indique dans l'article.
Je pense aussi que les interruptions n'apportent pas grand chose dans ce type d'utilisation.

Qu'en pensez-vous ?
Titre: Re : Barrière infra rouge et interruptions
Posté par: Cevenol38 le juin 19, 2016, 09:33:28 pm
Exactement, au début j'avais peur que rien ne soit détecté mais en fait la fréquence d'exécution de la boucle loop est telle qu'il n'y a aucun risque :).
Mon commentaire à 15 n'est plus à jour en effectuant de nombreuses mesures je l'ai augmenté à 100 qui semble vraiment une valeur seuil.
Tout fonctionne bien à présent :), reste à affiner le code mais je suis sur la bonne voie ;).
Merci à tous, le fait d'exposer mon problème m'a permis de le voir sous un autre angle.
Titre: Re : Barrière infra rouge et interruptions
Posté par: Dominique le juin 19, 2016, 10:06:53 pm
Merci pour votre contribution qui a eu le mérite d'enrichir plusieurs sujets utiles.

J'ajouterai que je penche en ce moment pour des détecteurs IR à réflexion à base de TCRT5000L, qui sont vendus sous forme de mini carte équipée d'un circuit intégré donnant un vrai signal logique D0 en plus du signal analogique A0.

(http://www.locoduino.org/local/cache-vignettes/L350xH350/tcrt5000l-68e4e.jpg?1466265072)

On en trouve à environ 1,5€ là par exemple : http://www.ebay.fr/itm/Infrared-reflective-Photoelectric-Switch-IR-Barrier-Line-Track-sensor-TCRT5000L-/310536079942?hash=item484d648a46:g:eQsAAOxyhodRzUaD (http://www.ebay.fr/itm/Infrared-reflective-Photoelectric-Switch-IR-Barrier-Line-Track-sensor-TCRT5000L-/310536079942?hash=item484d648a46:g:eQsAAOxyhodRzUaD)