Pin interruption et pin digital

Bonjour,

Peut-on faire la même chose qu'un pin INT0 et INT1 (broche 2-3 digital de l'arduino Uno), avec une autre pin digital (broche 4 à 13).

Vous me direz, pourquoi ne prend t-il pas les pin INT0 et INT1 tout simplement ? Le problème c'est que j'ai déja un codeur de branché dessus et que je ne veux/peux pas y toucher.

J'ai un capteur qui donne un signal 0/12V (qu'on peut associer 0V => 0, 12V => 1) que je convertie en 0/4.8V (pas les bonnes résistances pour le 0/5V m'enfin pas grave), j'aimerais compter le temps qu'il se passe entre 2 fronts montants, ce qui me donne T (F=1/T), et avec cette fréquence je peux traiter mon signal.

Le code que j'ai fait et qui fonctionne sur la broche INT0 : (je sais pas si ça peut aider)

float  vit;
int frequence;
int count;

void setup()
{
// pinMode(Sensor, INPUT); // met la pin 2 en entrée
 Serial.begin(115220);   //définition de la vitesse du port série
 attachInterrupt (0,vitesse, RISING);
}

void loop()
{
  // mesurer la fréquence comme le nombre de fronts montants en 1 s.
 frequence = count;
 count = 0;
 // traiter la fréquence
 vit=frequence/4.5;
 Serial.print(vit);
 Serial.println(";");
 delay(1000);  // attendre une seconde pour avoir la fréquence en Hz
}

void vitesse()
{
  count++;
}

Merci d'avance. Cordialement.

Oui tu peux "raccorder" une interruption sur n'importe quelle E/S raccordée à un port digital. Ce qui inclue les broches référencées par Arduino de A0 à A5 en plus des broches D0 à D13. Attention sur les cartes Nano et Mini-pro les entrées A6 et A7 sont purement analogiques.

Les interruptions sont dans ce cas des interruptions PCINT0 à PCINTn c'est à dire des interruptions sur les ports au contraire de INT0 à INTn qui sont des interruptions sur des broches précises.

Pour les mettre en œuvre il existe des bibliothèques toutes faites. Il est aussi possible de les mettre en œuvre en configurant les registres dédiés du micro-controleur, mais pour cela il faut lire la datasheet du micro.

Attention, quelque soit le moyen choisi pour utiliser les interruptions, il existe un ordre de priorité. Toutes les interruptions ne sont pas égales, voir dans la datasheet.

Bonjour,

merci pour l'information des interruptions sur broche numérique, je voudrais faire l'interruption sur la D10 donc PCINT 2

http://playground.arduino.cc/Main/PcInt

/* Pin to interrupt map: * D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2 * D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0 * A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1 */

Le probleme c'est que je ne comprend pas comment faire : avec un INT0, tu fais :

attachInterrupt (0,vitesse, RISING);

qui va appeler la fonction "vitesse" sur chaque front montant sur la broche 0.

pour une PCINT2 es ce que c'est :

attachInterrupt (PCINT2,vitesse,RISING);

je ne trouve pas les bibliothèques dont tu m'as parlé.

Cordialement

Je sais qu'il en existe, cela ne veux pas dire que je les ai trouvée et utilisée. En fait je ne les ai pas cherché car j'avais fait le choix de comprendre le fonctionnement interne du micro et donc j'ai manipulé les registres. Dans le principe les interruptions PCINT ne fonctionnent que sur un changement de niveau, l'option front n'est pas gérée. La gestion se passe en trois temps : 1) le micro te prévient qu'il y a eu une interruption sur le portx. (x = B, C ou D pour un atmega 328p). 2) c'est à toi de rechercher dans le registre adéquat quelle broche du port (de 0 à 7) a généré l'interruption. 3) c'est à toi de controler si le changement de niveau est bas vers haut ou l'inverse.

Ah ok j'ai du travail :D

Sinon sur un port analogique, je dois pouvoir faire :
car je veux faire un fréquencemètre (savoir la fréquence de mon signal)

float start_time=0;
int compteur;
mesure= analogRead(A2); //lecture de la broche analogique A2

void loop() {

   start_time = millis();
   while((millis()-start_time) < 1000){   // le nombre d'impulsion en 1 seconde donne la fréquence en hertz 

      if (mesure >= 818 ){ // 818 correspond à 4V
        compteur++; //j'incrémente
      }
   }
   frequence=compteur;
   compteur=0;
   vit=frequence/4.5;  // le constructeur dit 4.5 herz = 1 Nœud 

}

Des codes qui pourraient peut être t'intéresser http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/ http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-frequency-counter-library/

Merci.

J’ai essayé ce code :

#include <FreqCounter.h>

void setup() {
  Serial.begin(57600);                    // connect to the serial port
  Serial.println("Frequency Counter");
}

long int frq;
Void loop() {

 FreqCounter::f_comp= 8;             // Set compensation to 12
 FreqCounter::start(100);            // Start counting with gatetime of 100ms
 while (FreqCounter::f_ready == 0)         // wait until counter ready
 
 frq=FreqCounter::f_freq;            // read result
 Serial.println(frq);                // print result
 delay(20);
}

On voit la différence quand le capteur fonctionne et ne fonctionne pas, mais normalement quand il fonctionne il devrait m’indiquer entre 8 et 9 Hz, mais la il m’indique seulement 1 Hz.

Pourquoi ?

Si la PIN D8 est disponible, je te conseille d’utiliser l’Input Capture Pin (ICP1) de l’Atmega328P, mais va falloir lire un peu la datasheet :wink:

Je joins mes memo perso, qui peuvent peut-être te servir…

MEMO-CounterTimer.pdf (15.5 KB)

MEMO-Interruptions.pdf (5.78 KB)

Impossible de comprendre quoi que ce soit, malheureusement.

Pas de bol, t'as choisi la mauvaise librairie. Celle que tu as prise est recommandée pour les fréquences élevées. L'autre fait une mesure de période est elle est mieux adaptée aux basses fréquences. C'est expliqué au début, voir là:http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/

Super avec celui la j'arrive à avoir, la même fréquence que sur une broche interruption .

Merci beaucoup

Bonjour,

Quand je fais les essais avec seulement la carte UNO + le capteur (j’affiche avec Serial.print), tout marche nickel.

#include "FreqPeriod.h"

long int pp;
float periode=0;
float frequence=0;
float vitesse=0;
float mesure_pp=0;
float periode_s=0;
float vitesse_ms=0;

void setup() {
  Serial.begin(115200);
  FreqPeriod::begin();
}

void loop(){
  pp=FreqPeriod::getPeriod();
  mesure_pp=pp;
  
  if (pp==0) {
    Serial.print("Periode, Frequence, Vitesse = 0");
    Serial.println(" ");
    delay(1000);
  }
  else {
    calcul();
    affichage();
 }
}
  
void calcul(void) {

  periode=(mesure_pp*0.0625);
  periode_s=periode/1000000;
  frequence=1/periode_s;
  vitesse=frequence/4.5;
  vitesse_ms=vitesse*0.5144444;
}

void affichage(void) {
  Serial.print("Periode : ");
  Serial.print(periode_s);
  Serial.print(" ");
  Serial.print("Frequence : ");
  Serial.print(frequence);
  Serial.print(" ");
  Serial.print("Vitesse : ");
  Serial.print(vitesse_ms);
  Serial.println(" ");
  delay(1000);
}

maintenant quand je veux enregistrer sur une carte SD (avec un shield ethernet) et afficher sur un afficheur alphanumérique, cela me marque n’importe quoi (j’ai remarqué un décalage dans la table ascii)
exemple : normalement il marque :
V= 0.00 m/s

la il marque :
F< 830.28 1.s

d’autre fois il me marque seulement :
W=

// /////////////////////////////// 1. Entête déclarative ///////////////////////////////
#include <SPI.h> // Serial Peripheral Interface
#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD
#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD

#include "FreqPeriod.h"

const int brocheSDCardSelect=4; // broche utilisée pour sélectionner la SD card

long int pp;
float periode=0;
float frequence=0;
float vitesse=0;
float mesure_pp=0;
float periode_s=0;
float vitesse_ms=0;
int y=0;

LiquidCrystal lcd(10, 6, 5, 4, 8, 9); // broche afficheur alphanumérique 

int test; // Variable utilisée pour tester valeur renvoyée par fonctions SD Card

File file; // objet file
File root; // objet root pour le répertoire racine

void setup() {
  Serial.begin(115200);
    lcd.begin(16,2); // Initialise le LCD avec 16 colonnes x 2 lignes
  delay(10); // pause rapide pour laisser temps initialisation
 
  //--- Initialise l'utilisation de la carte mémoire SD en mode SPI ---
  pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
  digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet (on ne peut donc pas utiliser la connexion RJ45 et la carte SD en même temps)

  //--- Si la carte SD n'est pas inséré il y a une erreur ---
  if (!SD.begin(4)) {
   lcd.setCursor(0,0);
   lcd.println("Erreur SD");
   lcd.setCursor(0,1);
   lcd.print("RESET");
   delay(1000000);
  }
  else { // si initialisation réussie
   lcd.print("Init reussie"); // message port Série
   delay(1000);
   lcd.clear();
  
    //--- Affiche le contenu du répertoire ---
   root = SD.open("/"); // ouvre la carte SD à la racine
   lcd.print("Fichier ouvert");
   delay(1000);
   lcd.clear();
    
  } // fin si, initialisation réussie
   
  test=SD.remove("data.txt"); // test si dans la carte Sd il y a un fichier data.txt si oui il est supprimé
  file = SD.open("data.txt", FILE_WRITE); // ouverture du fichier data.txt en écriture
  file.println("NumeroMesure;Vitess_eeau;Temps"); // écriture sur la premier ligne du fichier data.txt
  file.close(); //fermeture fichier data.txt
  
  FreqPeriod::begin();
}

void loop(){
  pp=FreqPeriod::getPeriod();
  mesure_pp=pp;
  
  if (pp==0) {
    lcd.setCursor(0,0); //1ere col - 1ere ligne - positonne le curseur à l'endroit voulu (colonne, ligne)
    lcd.print("V="); // écrit V= sur l'afficheur LCD
    lcd.setCursor(3, 0); // 1ere col - 4eme ligne - positionne le curseur à l'endroit voulu (colonne, ligne) 
    lcd.print("0.00"); //écrit la variable vitesse_ms sur le LCD 
    lcd.setCursor(13,0); // 1ere col - 14eme ligne - positionne le curseur à l'endroit voulu (colonne, ligne)
    lcd.print("m/s");
    
    delay(1000); //pause d'1 seconde
    lcd.clear();
    
    file = SD.open("data.txt", FILE_WRITE); // fermeture fichier
    file.print(y), file.print(';'); // premiere colonne, écriture du numéro de mesure 
    file.print("0"), file.print(';'); // deuxieme colonne, écriture de la vitesse de l'eau                             
    file.print(millis()); // sixieme colonne, écriture du temps en ms        
    file.println(); // saute une ligne  
    file.close(); // fermeture fichier 
   
  }
  else {
    calcul();
    ecritureSD();
    ecritureLCD();    
    y++;
 }
}
  
void calcul(void) {
  periode=(mesure_pp*0.0625);
  periode_s=periode/1000000;
  frequence=1/periode_s;
  vitesse=frequence/4.5;
  vitesse_ms=vitesse*0.5144444;
}

void ecritureSD(void) { // Boucle écriture sur la carte SD et dans le fichier data.txt

  file = SD.open("data.txt", FILE_WRITE); // fermeture fichier

  file.print(y), file.print(';'); // premiere colonne, écriture du numéro de mesure 
    
  file.print(vitesse_ms), file.print(';'); // deuxieme colonne, écriture de la vitesse de l'eau               
                
  file.print(millis()); // sixieme colonne, écriture du temps en ms 
         
  file.println(); // saute une ligne
  
  file.close(); // fermeture fichier 
}
   
void ecritureLCD(void){ // Boucle affichage LCD

      
  lcd.setCursor(0,0); //1ere col - 1ere ligne - positonne le curseur à l'endroit voulu (colonne, ligne)
  lcd.print("V="); // écrit V= sur l'afficheur LCD
  lcd.setCursor(3, 0); // 1ere col - 4eme ligne - positionne le curseur à l'endroit voulu (colonne, ligne) 
  lcd.print(vitesse_ms,2); //écrit la variable vitesse_ms sur le LCD 
  lcd.setCursor(13,0); // 1ere col - 14eme ligne - positionne le curseur à l'endroit voulu (colonne, ligne)
  lcd.print("m/s");
    
  delay(1000); //pause d'1 seconde
  lcd.clear();
}

j’utilise FreqPeriod, avec le signal branché sur la broche 7 digital.
mon afficheur alphanumérique est branché sur les broches 10, 6, 5, 4, 8, 9.

Je ne comprend pas pourquoi il y a ce problème.

Pouvez-vous m’aider ?

Cordialement.

L’autre truc bizarre c’est que

if (!SD.begin(4)) {
   lcd.setCursor(0,0);
   lcd.println("Erreur SD");
   lcd.setCursor(0,1);
   lcd.print("RESET");
   delay(1000000);
  }
  else { // si initialisation réussie
   lcd.print("Init reussie"); // message port Série
   delay(1000);
   lcd.clear();
  
    //--- Affiche le contenu du répertoire ---
   root = SD.open("/"); // ouvre la carte SD à la racine
   lcd.print("Fichier ouvert");
   delay(1000);
   lcd.clear();

Fonctionne très bien.

Il marque bien Init reussie puis fichier ouvert sans décalage.

Est-il possible de dire à freqperiod de prendre en compte seulement la pin 7 digital ?